6

以前に、クライアントまたはサービスでの Async-Await の適用に関連するこの質問を投稿しました。質問と密接に関連しているため、この質問に進む前に質問を読んでください。

回答に基づいて、C# 4.0 (TPL) および C# 5.0 (Async - Await) のコードをテストしました。サービスによって提供されるメソッドの非同期および同期バージョンを使用してサービスを呼び出し、それぞれの場合に使用されるスレッドの数を比較しています。以下は、使用されているリソースをテストするために使用しているコードです。

主な方法

List<Task<string>> tasksList = new List<Task<string>>();
List<int> asyncThreads = new List<int>();
List<int> tplThreads = new List<int>();
Stopwatch watch = new Stopwatch();
watch.Start();

// Call the Async version of the method
for (int i = 0; i < 500; i++)
{
    tasksList.Add(GetNameFromServiceAsync("Input" + i.ToString(), asyncThreads));
}

Task.WaitAll(tasksList.ToArray());

watch.Stop();

foreach (var item in asyncThreads.Distinct())
{
    Console.WriteLine(item);
}

Console.WriteLine("(C# 5.0)Asynchrony Total Threads = " + asyncThreads.Distinct().Count());
Console.WriteLine(watch.ElapsedMilliseconds.ToString());

watch.Restart();

tasksList.Clear();

// Call the normal method
for (int i = 0; i < 500; i++)
{
    tasksList.Add(GetNameFromService("Input" + i.ToString(), tplThreads));
}

Task.WaitAll(tasksList.ToArray());

watch.Stop();

foreach (var item in tplThreads.Distinct())
{
    Console.WriteLine(item);
}

Console.WriteLine("(C# 4.0)TPL Total Threads" + tplThreads.Distinct().Count());

Console.WriteLine(watch.ElapsedMilliseconds.ToString());

サービスへの非同期および同期コール

static async Task<string> GetNameFromServiceAsync(string name, List<int> threads)
{
  Console.WriteLine(" Start Current Thread : " + System.Threading.Thread.CurrentThread.ManagedThreadId);
    var task = await client.GetNameAsync(name);
    threads.Add(System.Threading.Thread.CurrentThread.ManagedThreadId);
   // Console.WriteLine("End GetNameFromServiceAsync Current Thread : " + System.Threading.Thread.CurrentThread.ManagedThreadId);
    return task;
}

static Task<string> GetNameFromService(string name, List<int> threads)
{

    var task = Task<string>.Factory.StartNew(() =>
        {
            threads.Add(System.Threading.Thread.CurrentThread.ManagedThreadId);
         //   Console.WriteLine("GetNameFromService Current Thread : " + System.Threading.Thread.CurrentThread.ManagedThreadId);
            return client.GetName(name);
        });

    return task;
}

今、私は答えに取り組み、次の結果を見つけました:

  • サービスを 500 回呼び出すと、4 ~ 5 スレッドしか使用しません。
  • TPL 呼び出しは、約 44 ~ 45 のスレッドを作成します。
  • 非同期呼び出しの時間は約 17 ~ 18 秒です
  • TPL 呼び出しの時間は約 42 ~ 45 秒です。

他のコミュニティ メンバーにも役立つように、調査結果についてフィードバックをお寄せください。それは私の以前の質問の答えですか??

編集

Q. 私の観察によると、TPL の Task.Factory.startNew の代わりに Async-Await を使用すると、消費するスレッドが少なくなります。これはどのくらい正しいですか?いいえの場合、そのような比較を行う正しい方向は何ですか?

Q. 私は async - await を学んでいるので、ある種の比較としっかりしたコードによってその価値を証明したいと思っています。

4

1 に答える 1

16

クライアント側async(同期コードと比較して) は、通常、メモリをわずかに消費しますが、応答性が向上します。

サーバー側async(同期コードと比較して) は、通常、メモリ/スレッドの使用量を減らすことでスケーラビリティを向上させます。これらの利点は、async(マルチスレッド コードと比較して) クライアント側にも当てはまります。

これらはどちらも極端な一般化であり、間違っている状況も確かにあります。

アップデート:

私の観察によると、Async-Await ... を使用すると、消費するスレッドが少なくなります。

async/await保守可能な非同期コードを有効にします。それ自体では、スレッドの作成とは何の関係もありません。ただし、バックグラウンド タスクを作成するためにTask.Run(または) と共に使用されることがよくあります。Task.Factory.StartNew

私は非同期を学んでいるので、待って、ある種の比較と堅実なコードによってその価値を証明したいと思います。

asyncおよびawaitはコンパイラ変換です。それらは非同期プログラムの作成を容易にします - それだけです。

それらを同期コードと比較すると、通常、応答性やスケーラビリティが改善されていることがわかります。それらを既存の非同期コードと比較すると、通常はわずかに効率が低下しますが、コードの保守性という点ではそれを補って余りあります。

于 2012-10-01T13:03:59.753 に答える