2016-08-31 7 views
0

私はこれを行うことができることがしたいと思います。もちろんタスクのOnCompletedコールバックはどこにありますか?

class MyClass 
{ 
    IRepo repo; 
    public MyClass(IMyRepo repo) { this.repo = repo; } 

    long ID { get; set; } 
    string Prop1 { get; set; } 
    string Prop2 { get; set; } 

    public async Task LoadAsync() 
    { 
     await Task.WhenAll(
      repo.GetProp1ByIDAsync(ID).OnComplete(x => Prop1 = x), 
      repo.GetProp2ByIDAsync(ID).OnComplete(x => Prop2 = x) 
     ); 
    } 
} 

が、私はTaskため、このOnComplete拡張子を持つすべての標準ライブラリを見つけるように見えることはできません。私は本当に自分自身を作成する必要がありますか、すでにこの拡張メソッドを持っているライブラリがありますか?私はContinueWithがあることがわかりますが、それは私にはまだ解けない結果を与えていません、私はまだawaitまたは.Resultそれを持っているので...スレッドをブロックしないでしょうか?これが完了するまで、2番目のrepoコールを保持しますか?それを保持していない場合、その結果がまだラップされているのはなぜですか?アンラップされた結果を返すのはよりクリーンですか?または私は何かを逃していますか?

+1

サイドノート:この(タスクonCompleteの非同期(async) 'のpublic static:' async'とコールバックを混合読者のために混乱することができるが...私は1つの文のfunctionlikeを実装するためのライブラリを探していないでしょうタスク t、アクションコールバック){callback(await t);} ' –

答えて

2

まず、.WaitAllの代わりにawait Task.WhenAll(...)を取得する必要があります。

ContinueWithは完了時に別のタスクを開始するために必要なものです。 ContinueWithに渡されたアンラップした結果の.Resultを呼び出すと、タスクが既に完了しているのですぐに戻ります。待っていると同じことが続きます。

最初のタスクに.ContinueWithを呼び出すことは、2番目のタスクには何の影響もなく、後でawait Task.WhenAll(...)を使用して待機するので、パラレルで実行されます。

チェックアウトlink ReadFileAsyncの例を参照してください。

1

タスク用のこのOnComplete拡張機能を持つ標準ライブラリが見つからないようです。私は本当に自分自身を作成する必要がありますか、すでにこの拡張メソッドを持っているライブラリがありますか?私はContinueWithがあることを知っているが、それは私にアンラップされた結果を与えていない、私はまだそれを待たなければならないか、それとも...スレッドをブロックしないだろうか?

ContinueWithは、お探しの方法です。 Resultは、コールバックが呼び出されるまでに完了しているため、タスクをブロックしません。

ただし、ContinueWithは、危険な低レベルのAPIです。あなたが代わりにawaitを使用する必要があります。

public async Task LoadAsync() 
{ 
    await Task.WhenAll(
     LoadProp1Async(), 
     LoadProp2Async() 
    ); 
} 

private async Task LoadProp1Async() 
{ 
    Prop1 = await repo.GetProp1ByIDAsync(ID); 
} 

private async Task LoadProp2Async() 
{ 
    Prop2 = await repo.GetProp2ByIDAsync(ID); 
} 
関連する問題