私はmain()
にこの構造を持っています。
_var tasks = new List<Task>();
var t = Task.Factory.StartNew(
async () =>
{
Foo.Fim();
await Foo.DoBar();
});
//DoBar not completed
t.Wait();
//Foo.Fim() done, Foo.DoBar should be but isn't
_
ただし、tに_.Wait
_を指定すると、DoBar()
の呼び出しが完了するまで待機しません。実際に待つにはどうすればよいですか?
Task.Factory.StartNew
でasync-await
を使用することは推奨されません。代わりにTask.Run
を使用する必要があります。
var t = Task.Run(
async () =>
{
Foo.Fim();
await Foo.DoBar();
});
Task.Factory.StartNew
apiは、 タスクベースの非同期パターン(TAP) およびasync-await
の前に構築されました。ラムダ式でタスクを開始しているため、たまたま非同期でタスクを返すため、Task<Task>
を返します。 Unwrap
は内部タスクを抽出しますが、Task.Run
は暗黙的にそれを行います。
より詳細な比較のために、関連するStephen Toubの記事が常にあります: Task.Run vs Task.Factory.StartNew
タスクをUnwrap()
ingすることで、必要な機能が得られるようです。この背後にある理由を理解できるかどうかはよくわかりませんが、うまくいくと思います。
_var t = Task.Factory.StartNew(
async () =>
{
Foo.Fim();
await Foo.DoBar();
}).Unwrap();
_
編集:Unwrap()
の説明を探しました:_Creates a proxy Task that represents the asynchronous operation of a Task<Task<T>>
_これは伝統的にタスクがやったことだと思っていましたが、unwrapを呼び出す必要があるならそれでいいと思います。
私は最近、同様の問題に直面し、あなたがする必要があるのは、DoBar()
が何らかの値を返し、待機の代わりに.Resultを使用することであることがわかりました。
var g = Task.Run(() => func(arg));
var val = g.Result;
これは、func
が出力を返し、valに割り当てるのを待ちます。