9

await最初のメソッドが呼び出される前に、非同期メソッドの開始時に高価なコードを使用するのは悪いことですか? TaskEx.Runこのコードは代わりに a でラップする必要がありますか?

public async Task Foo()
{
    // Do some initial expensive stuff.
    // ...

    // First call to an async method with await.
    await DoSomethingAsync;
}
4

2 に答える 2

10

リードが言うように、それは本当に文脈に依存します。コードはある時点で実行する必要がありますが、コンテキストによっては、重要なスレッドではなくスレッド プール スレッドで実行される場合があります。

を使用するのではなく、次をTask.Run使用しますTaskEx.Yield

public async Task Foo()
{
    await TaskEx.Yield();
    // Do expensive stuff
}

私の知る限り、これは基本的に呼び出し元にすぐに戻る方法ですが、残りの非同期メソッドをすぐにスケジュールできるようにします。Windows フォーム UI スレッドのようなものにいる場合は、すぐに UI スレッドに戻る (そしてそこで高価なコードを実行する) ため、これを行う意味はありませんが、コンテキスト内にいる場合は意味があります。現在のスレッドはブロックされるべきではありませんが、継続は別のスレッドで実行されます。

于 2011-12-09T17:15:43.147 に答える
5

必ずしも悪いわけではありませんが、予期しない結果が生じる可能性があります。呼び出し元がコードが完全に非同期で動作することを期待している場合、高価なコードは同期的に実行されます。これにより、部分的に同期メソッドのように動作するだけでなく、非同期にも動作します。これは、両方の世界の最悪の部分です (応答性のない非同期からの余分な複雑さ...)

可能であれば、最初の待機につながる「高価な」コードをできるだけ少なくすることをお勧めします。Task.Run(またはCTP で) を使用しTaskEx.Runて高価なコードをラップするか、高価なコードを独自の非同期メソッドに移動する (その上でawait) は、この場合に有益です。

于 2011-12-09T17:11:49.573 に答える