2011-06-20 12 views
1

WCFサービスを使用するSilverlightアプリケーションがあり、Wintellect Power Threadingライブラリを使用して、アプリケーションが続行される前にロジックが完全に実行されるようにします。これは、デリゲートを使用してアプリケーションにコールバックすることによって達成されるため、サービスコールが完全に終了した後でも続行できます。Silverlight - メソッドから戻る前に非同期呼び出しが終了するまで待つ

私のアプリケーションの別の部分で同じことを達成したいと思いますが、コールバックを使用しません。 WCFサービスを使用してデータベースからオブジェクトをロードし、これが返るのを待ってから、呼び出された元のメソッドからオブジェクトのIDを返します。

これを行うには、別のスレッドでオブジェクトをロードするヘルパーライブラリでWCFサービスの呼び出しを実行し、元のメソッドはヘルパーライブラリ(静的変数を使用)それが完了するのを待ってからそれを返します。

これは、この機能を実現するための最良の方法ですか?そうであれば、正しく実装されていない実装の詳細がここにあります。

public class MyHelper 
{ 

    private static Thread _thread; 
    private static User _loadedObject;   

    public static GetUser() 
    { 
     return _loadedObject; 
    } 

    public static void LoadObject(int userId) 
    { 
     _loadedObject = null; 
     ParameterizedThreadStart ts = new ParameterizedThreadStart(DoWork);   
     _thread = new Thread(ts); 
     _thread.Start(userId); 

    } 

    private static void DoWork(object parameter) 
    {    
     var ae = new AsyncEnumerator(); 
     ae.BeginExecute(DoWorkWorker(ae, Convert.ToInt32(parameter)), ae.EndExecute);  
    } 

    private static IEnumerator<Int32> DoWorkWorker(AsyncEnumerator ae, int userId) 
    { 
     // Create a service using a helper method 
     var service = ServiceHelper.GetService<IUserServiceAsync>(); 
     service.BeginGetUserById(userId, ae.End(), null); 
     yield return 1; 

     _loadedObject = service.EndGetUserById(ae.DequeueAsyncResult()); 
     _thread.Abort(); 
    } 
} 

私の方法は次のようになります。

public int GetUser(int userId) 
{ 
    MyHelper.LoadObject(userId); 
    User user = MyHelper.GetUser(); 
    while (user == null) 
    { 
     Thread.Sleep(1000); 
     user = MyHelper.GetUser(); 
    } 
    return user.Id; 
} 

ユーザーはヘルパーメソッド内の別のスレッドで実行されて取得するために呼び出すが、決してを返します。おそらく、これは歩留まりと呼び出しメソッドが眠っているためです。私は、ユーザーが別のスレッド上にあることを確認するために呼び出しをチェックしたので、すべてを別々にしておくべきだと思っています。

答えて

1

使用しているコンストラクト全体が、Silverlightの現在のベストプラクティスと一致しません。 Silverlightでは、データアクセスメソッド(もちろんWebServices経由)は非同期に実行されます。その周りにはデザインはしないでください。

一部のシナリオでは、サービスを連続して呼び出す(これは同期とは異なります)ことができます。 this blog postでは、リモート呼び出しのCompletedイベントを購読してその間にUIをブロックすることで、これを達成する方法を示しました。その間、ワークフローは通常の非同期呼び出しのように見えます。あなたがあなたのサービスコールの各々について「同期」BeginEndメソッドを呼び出すことができ、あなたのサービス参照用に作成されたインタフェースに対してコーディングする場合

+0

私は同意し、私のアプリケーションはベストプラクティスに従います。この質問は実験的であり、それらの慣行から逸脱していました。この質問は、その結果を計算するために、すべてが非同期的にサービスを提供し、計算された値を返すことのできるいくつかのメソッドを呼び出さなければならないメソッドを呼びたいというシナリオの一部です。呼び出し先がこの値を取得した後は、オプションで別のメソッドを同じように実行する必要があります。私は、処理するコールバック/イベントの数を考えれば、できるだけ単純にこのシナリオをコーディングする方法を検討していました。 –

1

Silverlightアプリケーションからサーバーへの呼び出しはUIスレッドで発生するイベントを使用します。私はこれがブラウザのSilverlightホスト環境の一部であり、回避できないと思います。したがって、別のスレッドからサーバーにコールバックしようとすると、うまく終了しません。 UIスレッドのプログラムコードで待機している場合は、WCF呼び出しからコール結果イベントを取得しないでください。

can UIスレッド上でコールバックを持つ非UIスレッドからの同期呼び出しをシミュレートしますが、これはおそらく必要ではありません。それは、Silverlightがあなたに与える非同期呼び出しでプログラムのロジックを動作させることができます。

1

、我々はその後、End方法が完了した後に実行するAction<T>に渡します。ディスパッチャーからこれを行う必要があることに注意してください。これは、コールが行われた場所にコールが書き込まれた後に実行されるコードとして同期呼び出しを行うことに非常に近く、サービスコールの完了後に実行されます。ただし、ラッパーメソッドを作成する必要がありますが、ラッパーを隠して自動的に生成することで回避しました。仕事のように思えるが、そうではなく、すべてのイベントハンドラーよりもエレガントに終わる。このパターンに関する詳細情報が必要な場合はお知らせください

関連する問題