1

非同期プログラミングに関する 2 つのパラダイムを示し、皆さんのコメントに耳を傾けたいと思います。

A.

ライブラリで次のようなメソッドを作成し、GUI クライアントから使用したとします。

public async Task<TestObject> DoSomeWork(string aParam1, object aParam2)
{
   TestObject testObj = new TestObject();
   ...fill in params to testObj...
   await MethodCallAsync(testObj);
   ....do other work synchronous.....
   ....continue fill testObj properties...
   await Task.Delay(1000) // just a delay for no reason
   ...continue synchronous work.....
   return testObj;
}

わかりましたが、これは私の GUI コンテキストを小さな呼び出し部分に分割しますよね? または、メソッド async を宣言した瞬間から、内部のすべての操作に対して Task が作成されるかどうかわかりませんか?

はいの場合は問題ありません。非同期を宣言して、生活を続けることができます。

いいえ、次のアプローチを取りたいので、メソッド呼び出し全体が終了して結果が得られるまで、GUI をまったく邪魔しないようにして、呼び出し元のメソッドで何かを行います。

B.

別のアプローチがあります。

public async Task<TestObject> DoSomeWork(string aParam1, object aParam2)
{
   TestObject testObj = new TestObject()
   ..fill state params....
   return await Task.Factory.StartNew((state) =>
   {
      //But now I need to do async/await in here
      // is it a good practice to async await lambdas?
      // async/await practices say it's ok as long sas it is not becoming async void
      // which in our case is not.
      await MethodCallAsync(testObj);
       ....do other work synchronous.....
       ....continue fill state properties...
       await Task.Delay(1000) // just a delay for no reason
       ...continue synchronous work.....
       return state; // Our state and TestObject to examine after completion

   }, testObj);
}

私たちの問題は、ラムダを非同期化する必要がある場合だけではなく、それを行うと a が返され、Task<Task<TestObject>>間違いなくそれを望んでいません。

パイプラインでこれを呼び出す必要があります。ほとんどの場合、GUI クラスです。

private async void SomethingClickedOrTouched(object sender, EventArgs e)
{
   await RunThisAsyncToDoYourJob();
}

private async Task RunThisAsyncToDoYourJob()
{
   TestObject testObj = await myObject.DoSomeWork("param1", anotherObject);
}

それは私を少し悩ませているだけで、非同期プログラミングの詳細を本当に知りたいと思っています。

とにかく、A パラダイムは正しいアプローチであり、コード内のタスク ラムダが完全に同期している場合にのみ B パラダイムを使用しますか? 前もって感謝します。

よろしく。

4

1 に答える 1

6

メソッドを記述する適切な方法は、キャプチャされたコンテキストで再開する必要がない場合はいつでもasync使用することです。これは通常、すべての「ライブラリ」コードに対して行われます。ConfigureAwait(continueOnCapturedContext: false)

これにより、GUI コンテキストが小さな呼び出し要素に分割されますよね?

はい(使用していないためConfigureAwait)。

または、メソッド async を宣言した瞬間から、内部のすべての操作に対して Task が作成されるかどうかわかりませんか?

はい、メソッドを表すasyncを作成します。ただし、 があるからといって、そのコードがバックグラウンド スレッドで実行されているわけではありません。TaskasyncTask

それは a を返しますがTask<Task<TestObject>>、間違いなくそれは望ましくありません。

Task.Factory.StartNew誰もが非同期タスクに使用するというアイデアをどこで得ているか知りたいです。Task.Runバックグラウンド スレッドでコードを実行する場合に優れています


asyncのブログに紹介がありますので、参考にしてください。

于 2013-08-25T02:13:17.793 に答える