11

非同期メソッドについて調べてみましたが、独自の非同期メソッドを作成しようとしています。このメソッドは、エラー ログのリストを返す Web サービス呼び出しです。正しく理解しているかどうかわからないので、コードを共有して、何か違うことをする必要があるかどうかを確認したいと思いました。

コードで実行したいのは、メソッドGetAllErrorLogs()を呼び出してエラーログのリストを返すことだけです。これは同期メソッドです。すべてのエラー ログを取得するのに 1 秒かかる場合があるため、GetAllErrorLogs()メソッドを呼び出したら、他のことを行う機会が必要です。これがコードです。

[WebMethod]
public async Task<List<ErrorLog>> GetAllErrorLogs()
{
    List<ErrorLog> errorLogs = new List<ErrorLog>();

    await System.Threading.Tasks.Task.Run(() => {
        errorLogs = ErrorLogRepository.GetAllErrorLogs();
    });


    if (errorLogs == null)
        return new List<ErrorLog>();

    return errorLogs;
}

ありがとう!

4

5 に答える 5

9

最近、サーバー側のThatConferenceで講演を行いましたが、この問題についてはスライドで説明しています。async

Task.Runサーバー側では、作業をスレッド プールにキューイングする およびその他の構造の使用を避けたいと考えています。可能な限り、スレッド プールのスレッドをリクエストの処理に使用できるようにします。

したがって、リポジトリに非同期メソッドGetAllErrorLogsAsyncがあり、それ自体が非同期であることが理想的です。GetAllErrorLogs非同期にできない場合は、直接呼び出すこともできます( を削除しますawait Task.Run)。

すべてのエラー ログを取得するのに 1 秒かかる場合があるため、GetAllErrorLogs() メソッドを呼び出したら、他のことを行う機会が必要です。

GetAllErrorLogsAsync利用可能な場合、これは を使用して簡単に実行できますTask.WhenAll。ただし、GetAllErrorLogsが同期の場合は、リクエストで並列作業を行うことによってのみこれを行うことができます (たとえば、 のTask.Run後に を複数回呼び出すなどTask.WhenAll)。

サーバー上の並列コードには、非常に恐れを持ってアプローチする必要があります。非常に限られた一連のシナリオでのみ許容されます。asyncサーバー側での全体的なポイントは、リクエストごとに使用するスレッドを少なくすることです。並列化を開始すると、反対のこと、つまりリクエストごとに複数のスレッドを実行することになります。これは、ユーザー ベースが非常に小さいことがわかっている場合にのみ適切です。そうしないと、サーバーのスケーラビリティが失われます。

于 2013-08-21T20:54:10.827 に答える