後で実行するタスクのキューを保持するクラスがあり、async Task<T>
メソッドがある場合、その非同期メソッドを実行せずにキューに入れるにはどうすればよいですか?
このタスクを「遅延」させたいので、メソッド本体で待機されているかのように、呼び出し元が後で実行されることを確認します。---呼び出し元は、私が後でタスクをキューに入れたことを知らないはずです。
現在、キューがいっぱいの場合Task<T>
は、実行されていない新しいここを作成して返します。これ.Result
により、プライベート非同期メソッドのが返されます。
public async Task<T> ExecuteAsync<T>(T transaction) {
if (mustDelay) {
Task<T> task = new Task<T>(t => executeAsync((T) t).Result, transaction);
enqueue(task);
return await task;
}
return await executeAsync(transaction);
}
private async Task<T> executeAsync<T>(T transaction) {
await someWork();
return transaction;
}
他のタスクが完了すると、Iはデキューし、Start()
そのエンキューされたタスクは次のようになります。
dequeuedTask.Start();
これにより、呼び出し元は、メソッドから待機中の結果を返す場合と同じ同期を確認できますか?
非同期メソッドのタスク結果を実行せずにキューに入れるにはどうすればよいですか?
簡単な答え:できません。async
メソッドを呼び出すと、そのメソッドが実行されます。必然的に実行を開始します。通話を延期できるようにしたい場合は、それを行う何かで通話をラップする必要があります。
一例としてFunc<Task<T>>
、あなたが私たちと共有するように設計したほんの少しのコードがTask<T>
、将来行うこの呼び出しを表すpromise()も返すことができるようにすることを示唆している場合を除きます。サンプルコードのように、すべてを別のタスクでラップすることもできますが、IMHOは、async
メソッドを呼び出すためだけにスレッドプールスレッドを拘束する(そして場合によっては新しいものを作成する)ため、かなり手間のかかるアプローチです。
それを達成するためのより良い方法(IMHO)は、を使用することTaskCompletionSource<T>
です。をFunc<Task>
キューに格納できます。キューは戻り値を使用してを設定しTaskCompletionSource<T>
、タスクを開始できると判断したら、を呼び出しますFunc<Task>
。
何かのようなもの:
public Task<T> ExecuteAsync<T>(T transaction) {
if (mustDelay) {
TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
enqueue(async () =>
{
tcs.SetValue(await executeAsync(transaction));
});
return tcs.Task;
}
return executeAsync(transaction);
}
ここで、は必要ありませんことに注意ExecuteAsync<T>()
する必要がasync
。TaskCompletionSource<T>
'タスクを返すか、executeAsync<T>()
メソッドによって返されたタスクを返します(ちなみに、名前が大文字と小文字だけが異なる2つのメソッドを持つことは、私見では恐ろしい考えです)。
また、キューにはFunc<Task>
オブジェクト、またはオブジェクトが格納されることにも注意してくださいAction
(通常async void
、上記の匿名メソッドなどのメソッドでは嫌われますが、そもそも例外処理を表示しなかったため、次の場所で正常に機能することがわかります。この場合)。アイテムをデキューすると、そのデリゲートが呼び出されます。必要に応じて、これは「ファイアアンドフォーゲット」(Action
デリゲートを格納する場合)になるか、デリゲートをデキューして呼び出すメソッドがデリゲートの戻り値を待つ場合があります(Func<Task>
デリゲートを格納する場合)。
残念ながら、あなたの質問はかなり曖昧です。したがって、これ以上のものを提供することはできません。さらにヘルプが必要な場合は、質問を改善して、達成しようとしていること、具体的に理解するのに問題があることを明確に示す、最小限、完全、検証可能な優れたコード例と、それを詳しく説明してください。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加