2017-07-12 11 views
2

Actionに相当するasyncは、Func<Task>です。非同期ラムダアクションからFunc <Task>への変換?

Func<Task> func = async() => 
     { 
      Console.WriteLine(@"waiting ..."); 
      await Task.Delay(300).ConfigureAwait(false); 
      Console.WriteLine(@"... finished"); 
     }; 

をしかし、Actionとしてそれを記述することも可能である:

したがって、私たちは書くことができます。これは、文法的に正しい

Action action = async() => 
     { 
      Console.WriteLine(@"waiting ..."); 
      await Task.Delay(300).ConfigureAwait(false); 
      Console.WriteLine(@"... finished"); 
     }; 

Action actionをどのようにしてFunc<Task> funcに変換できますか?

答えて

3

私は、2番目のスニペットがasync voidに似ていると思っています - ただの匿名です。

コンパイラは返されたタスクを管理し、それをデフォルトのスレッドプールに入れ、選択されたSynchroContextで「OK」であることを確認して継続を実行します"..私は残りの部分を覚えていません。async-voidの詳細を確認し、絶対に必要なとき以外は使用しないでください。例えば:例外処理の例の違いについて

注..

ああ、と私が答えるのを忘れて:それは本当にasync voidだ場合、あなたは変換できません。単に返されたTaskはなくなり、取得できません。

Action action =() => 
{ 
    Func<Task> yourRealTask = async() => 
    { 
     Console.WriteLine(@"waiting ..."); 
     await Task.Delay(300).ConfigureAwait(false); 
     Console.WriteLine(@"... finished"); 
    }; 

    // ** some compiler-generated code to register/run the task somewhere 
    // ** so it will be handled properly instea of being lost due to not 
    // ** returning the Task to the caller 

    return; 
} 

ので、効果的に、yourRealTaskが得られない..ですいくつかの幸運とあなたはリフレクション経由でいくつかの閉鎖からそれをハックかもしれないが、...ということをしない:あなたが持っているアクションのようなものです。ちょうどFunc<Task>を使用してください。

+0

素晴らしい応答をいただきありがとうございます – Syntony

0

最初のケースでは、通常のタスクファクトリが作成されます。

2番目の方法では、fire-and-forget async-voidメソッドが作成されますが、これはまれにしか使用されません。

コンパイラはとても使い勝手が良いので、1つの匿名メソッドから作成することができます。プログラマは、どちらが必要なのかはプログラマが決定します。

関連する問題