2

小さな問題に遭遇しました。asp.net Web API サービスを作成し、コントローラーに「async」を自動的に追加しました。もちろん、これには await を使用する必要があります。

私が抱えている問題は、コントローラーがサービスレイヤーに接続され、このサービスレイヤーがデータレイヤーに接続されていることです-このデータレイヤーは、GETのASYNCバージョンを呼び出して別のRESTサービスへの非同期呼び出しを行うレイヤーです-だからこれは簡単です。データ レイヤー メソッドを "async" キーワードを持つように変換し、HttpClient GetSync 呼び出しに await を配置します。

しかし、非同期/待機をサポートするサービスレイヤーは、戻り値の型をタスクに変更する必要がありますが、サービスレイヤーは実際には何もしていませんASYNC実際にHttpClient非同期メソッドを呼び出しているデータレイヤーへの呼び出し。

したがって、次のレイヤー構造があることを考えると、2 つのオプションがあります。

ASP.NET Web API >> サービス層 >> データ層

データ層でのみ async と await を使用し、それで完了します。

または、コントローラーとサービス層のメソッドに async と await を配置します。Task を返す必要があるため、これにはリファクタリングが必要です。

私がそれを完全に理解していない場合、技術的に唯一のブロッキング呼び出しはデータ層にあると思います。そのため、すべてのスレッドがスレッドプールを返して使用できるようにするには、データ層に async と await を配置することだけに注意する必要があります。

コントローラーでパターンを使用する必要があるのはいつですか???

どんな助けも楽しみにしています

4

2 に答える 2

6

コントローラーに「async」を自動的に追加しました。もちろん、これには await を使用する必要があります。

それは後ろ向きです。asyncを使用する必要がある場合にのみ、メソッドに追加する必要がありますawait

データ層でのみ async と await を使用し、それで完了します。

非同期メソッドを同期 API 内にラップしないでください。これは特にサーバー コードに当てはまりますasync

または、コントローラーとサービス層のメソッドに async と await を配置します。Task を返す必要があるため、これにはリファクタリングが必要です。

これが正しいアプローチです。次のガイドラインに従ってください。

  1. asyncコードでブロックしないでください。Task.Waitたとえば、またはを呼び出さないでくださいTask<T>.Resultこれによりデッドロックが発生する可能性があることをブログで説明していますが、ハッキングして確実に動作asyncさせたとしても、サーバー側での利点をすべて失うことになります。
  2. 避けてくださいasync void。特にサーバー側。
  3. Waitまたはの代わりにResult、 を使用しますawait。これは、待機中のメソッドがasync Taskまたはasync Task<T>である必要があることを意味します。つまり、待機中のメソッドを呼び出すメソッドも待機する必要があります。あなたasyncのコードを通して「成長」します。これは正常で正しいことです。

非同期プログラミングのベスト プラクティスに関する私の記事が参考になるかもしれません。

于 2013-09-19T15:07:20.120 に答える
1

呼び出し元のスレッドが意味のあることを何も行わない場合、作業を行う別のタスクを作成してもメリットはありません。

ただし、呼び出し元のスレッドに他にやるべきことがある場合、たとえば UI の応答性を維持する場合、呼び出し元のスレッドは別のタスクで関数を呼び出し、他のことを行い、結果が必要な場合は結果を待ちます。

例:

private async YourAsyncWebFunction(...)
{
    // do some processing
    // call other async functions ans wait for it to finish:
    await OtherAsync(...);
    var result = await OtherAsync2(...)
    if (result == ...) { ... }
}

private void MyMainFunction(...)
{
    var taskWebFunction = Task.Run( () => YourAsyncWebFunction(...));
    // do other things
    // after a while: you need the task to finish:
    await taskWebFunction;
    // do other things
 }

メイン関数がイベント ハンドラーの場合、Task.Run を実行する必要はありません。イベント ハンドラーを async として宣言するだけです。

イベント ハンドラーは、Task または Task <TResult>の代わりに void を返す唯一の非同期関数です。

private async void OnButton1_Clicked(object sender, ...)
{
     // do some processing
     await YourAsyncWebFunction(...)
}
于 2015-08-10T10:34:42.950 に答える