10

.NET 4.0 の await キーワードに代わる最良の方法は何ですか? 非同期操作の後に値を返す必要があるメソッドがあります。wait() メソッドがスレッドを完全にブロックしているため、非同期操作が役に立たないことに気付きました。UI スレッドを解放しながら非同期操作を実行するには、どのようなオプションがありますか?

4

2 に答える 2

4

あなたの基本的なオプションは

最も簡単な方法は、おそらく Async CTP をインストールすることです。私の知る限り、ライセンスは商用利用を許可しています。コンパイラにパッチを適用し、プロジェクトに含めることができる 150kb の dll が付属しています。

Taskとを使用できます.ContinueWith()。ただし、これは、例外処理とフロー制御に多少の努力が必要であることを意味します。

タスクは機能的な構造です。そのため、ループやブロックContinueWith()などの命令型構造とうまく混合できません。したがって、コンパイラが私たちを助けることができるように導入されました。fortry-catchasyncawait

コンパイラのサポートを利用できない場合 (つまり、.Net 4.0 を使用している場合) は、TAPを機能的なフレームワークと一緒に使用することをお勧めします。Reactive Extensionsは、非同期メソッドを処理するための非常に優れたフレームワークです。

開始するには、「リアクティブ拡張タスク」をグーグルで検索してください。

于 2012-11-19T19:58:10.727 に答える
2

awaitコルーチンのような動作を実装できますyield。私はこれを 4.5 以外のコードで使用しています。YieldInstruction非同期で実行する必要があるメソッドから取得されるクラスが必要です。

public abstract class YieldInstruction
{
    public abstract Boolean IsFinished();
}

YieldInstruction次に、 (タスクを処理する ae )のいくつかの実装が必要であり、TaskCoroutineこの方法で使用します(疑似コード):

public IEnumerator<YieldInstruction> DoAsync()
{
    HttpClient client = ....;
    String result;
    yield return new TaskCoroutine(() => { result = client.DownloadAsync(); });
    // Process result here
}

次に、命令の実行を処理するスケジューラが必要です。

for (Coroutine item in coroutines)  
{  
    if (item.CurrentInstruction.IsFinished())  
    {
         // Move to the next instruction and check if coroutine has been finished 
         if (item.MoveNext()) Remove(item);
    }
}

InvokeWPF または WinForms アプリケーションを開発する場合、適切なタイミングでコルーチンを更新していれば、呼び出しを回避することもできます。また、アイデアを拡張して、生活をさらに楽にすることもできます。サンプル:

public IEnumerator<YieldInstruction> DoAsync()
{
    HttpClient client = ....;
    client.DownloadAsync(..);

    String result;
    while (client.IsDownloading)
    {
        // Update the progress bar
        progressBar.Value = client.Progress;
        // Wait one update
        yield return YieldInstruction.WaitOneUpdate;
    }
    // Process result here
}
于 2012-11-20T09:49:45.137 に答える