0

同期呼び出しのSLWCFサポートを偽造する方法についてのアイデアを思いつきました。

基本的に、

private _completed;
private IList<Customer> _customers;
public void IList<Customer> GetAllCustomers()
{
    bool completed = false;
    DataServiceQuery<Customer> myQuery = this.Context.Customers;
    myQuery.BeginExecute(OnQueryExecuted, myQuery);

    while (!_completed)
      System.Threading.Thread.Sleep(67); //tried join also

    return _customers;
}

private void OnQueryExecuted(IAsyncResult result)
{
     var query = result.AsyncState as DataServiceQuery<Customer>;
    _customers = query.EndExecute(result).ToList();
    _isCompleted = true;
}

何が起こるかというと、これは永遠にループします。

whileループにブレークポイントを設定し、それを移動して実行を再開すると、次のミリ秒で結果が到着します。

したがって、結果を受け取るクエリのコールバックは、クエリが呼び出されたのと同じスレッドのキューに入れられると思います。

SLはこの動作を維持することを非常に決意しているようです。そのためmyQuery.BeginExecute、新しいスレッドでラップしても、同じ動作が得られます。

/ *編集:実際、それについて考えると、待機しているuiスレッドでコールバックをキューに入れます。これは、結果を得るときに必要がない理由でもありDispatcher.Invokeます。とにかく、私はいつでも専用スレッドで(待機が必要な)操作全体を実行し、そこで待機することができますが、これには大量のリファクタリングが必要になり、これを試すポイントは避けられます。* /

これを回避する方法はありますか?

4

1 に答える 1

1

これがハングする理由は、メソッドがUIスレッドにマーシャリングしているが、呼び出しEndExecuteでUIスレッドをブロックしているためです。Sleepスレッドをブロックするためにどの手法を使用するかは関係ありません。UIスレッドでメソッドが呼び出されると、何をしてもデッドロックが発生します。

SIlverlight環境で開発する場合は、同期メソッドを使用するのではなく、非同期でプログラムできる必要があります。C#5.0を使用している場合は、非同期/待機機能を使用できます。これにより、同期しているように見える非同期コードを記述できますが、コールバック/継続を利用する非同期呼び出しにコンパイルされます。そのバージョンにはまだアップグレードされていません。

于 2013-02-10T02:32:16.957 に答える