インターネットでは、async \ awaitはプログラミングの "天才的な革新"であることがよくあります。時にはそれはありますが、場合によっては、書かれる必要のあるコードを短縮できないと感じています。async/awaitシンタックスは、プログラマの手動スレッディングよりも本当に優れていますか、それほど役に立ちませんか?
私は3つの並列タスク(ダウンロード)が必要で、各ダウンロードの結果を処理したい場合(処理(コンソールへの出力SUM)は、ダウンロードごとに依存し、すべての結果を同時に必要とする場合# 1)、Iは、スレッドを使用してそれを行うことができますし、GetByteArray)が存在しないため、非同期を使用せずに/(としてここにいくつかの擬似コードを待つ:
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static int length = 0;
static HttpClient client =
new HttpClient() { MaxResponseContentBufferSize = 1000000 };
static void Main(string[] args)
{
CreateMultipleTasksAsync();
Console.ReadKey();
}
static void CreateMultipleTasksAsync()
{
Thread th1 = new Thread(ProcessURLAsync);
th1.Start("http://msdn.microsoft.com");
Thread th2 = new Thread(ProcessURLAsync);
th2.Start("http://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx");
Thread th3 = new Thread(ProcessURLAsync);
th3.Start("http://msdn.microsoft.com/en-us/library/67w7t67f.aspx");
//#2 there I need results of all 3 downloads (so it will wait for all 3 downloads being completed)
Console.WriteLine("\r\n\r\nTotal bytes returned: {0}\r\n", Program.length);
}
static void ProcessURLAsync(object urlObj)
{
string url = (string)urlObj;
var length = client.GetByteArray(url).Length;
/* //#1 there I need only a result of one current download (so it will wait only for current download being completed)
Console.WriteLine("\n{0,-58} {1}", url, length);*/
Program.length =+ length;
}
}
}
またはasync /のawaitを使って、このようにそれを行うことができます。
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
CreateMultipleTasksAsync();
Console.ReadKey();
}
static async Task CreateMultipleTasksAsync()
{
HttpClient client =
new HttpClient() { MaxResponseContentBufferSize = 1000000 };
Task<byte[]> download1 =
client.GetByteArrayAsync("http://msdn.microsoft.com");
Task<byte[]> download2 =
client.GetByteArrayAsync("http://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx");
Task<byte[]> download3 =
client.GetByteArrayAsync("http://msdn.microsoft.com/en-us/library/67w7t67f.aspx");
int length1 = (await download1).Length;
int length2 = (await download2).Length;
int length3 = (await download3).Length;
//#1 there I need results of all 3 downloads (so it will wait for all 3 downloads being completed)
Console.WriteLine("\r\n\r\nTotal bytes returned: {0}\r\n", length1 + length2 + length3);
}
}
}
とasync/await-wayは本当に短く、より良いですすべてのコードがコンパクトで、すべてが1つのメソッドCreateMultipleTasksAsyncにあり、私は追加のメソッドを作成してそれを委譲すべきではありません。
しかし、1回のダウンロード結果(#2のように他のダウンロードとは独立して)で何かをしたいのであれば、1つのコードを別の方法で取り出す必要があります。この方法。私はコードをこのように書くcant'tため
私は追加の方法が必要です。
...
Task<int> download1 =
ProcessURLAsync("http://msdn.microsoft.com", client);
Task<int> download2 =
ProcessURLAsync("http://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client);
Task<int> download3 =
ProcessURLAsync("http://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client);
int length1 = (await download1).Length;
//#3
Console.WriteLine("\n{0,-58} {1}", "http://msdn.microsoft.com", length1);
int length2 = (await download2).Length;
//#4
Console.WriteLine("\n{0,-58} {1}", "http://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", length2);
int length3 = (await download3).Length;
//#5
...
このコードにdownload2の結果は常にdownload1の結果を処理した後(#4でコンソールに出力する)処理されるためdownload3(#3)とdownload2(#4)の両方の結果を処理した後(#3)、download3の結果は常に処理される(#5でコンソールに出力される)。この場合の出力順序は常に同じです(たとえダウンロード3がダウンロード1よりはるかに早く完了しても、とにかく#3は#3の後に表示されます)。
しかし、私はdownload3が早くdownload1その後、完成したとき、#5は#3の前に表示したい場合、私は追加の方法ProcessURLAsync作成することを強制しています:
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
CreateMultipleTasksAsync();
Console.ReadKey();
}
static async Task CreateMultipleTasksAsync()
{
HttpClient client =
new HttpClient() { MaxResponseContentBufferSize = 1000000 };
Task<int> download1 =
ProcessURLAsync("http://msdn.microsoft.com", client);
Task<int> download2 =
ProcessURLAsync("http://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client);
Task<int> download3 =
ProcessURLAsync("http://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client);
int length1 = await download1;
int length2 = await download2;
int length3 = await download3;
//#1 there I need results of all 3 downloads (so it will wait for all 3 downloads being completed)
Console.WriteLine("\r\n\r\nTotal bytes returned: {0}\r\n", length1 + length2 + length3);
}
static async Task<int> ProcessURLAsync(string url, HttpClient client)
{
var length = (await client.GetByteArrayAsync(url)).Length;
//#2 there I need only a result of one current download, independently from other downloads (so it will wait only for current download being completed)
Console.WriteLine("\n{0,-58} {1}", url, length);
return length;
}
}
}
をし、この場合はそうではありません単一のダウンロードの結果を処理するために追加のメソッドProcessURLAsyncを作成する必要があるので、非同期/待機ウェイがより優れている理由を明らかにします。したがって、私のコードは、非同期/待機なしの最初のサンプルのコードに非常に似ています。
async/await-wayが3つの理由で明らかにスレッドウェイより優れているという事実を無視した場合 - 1)オブジェクトとしてデリゲートにURLを渡してから文字列にキャストする必要があります.2) (デリゲートから値を返すことができないため)静的プロパティProgram.lengthを作成する必要なしに長さ(length1、length2、length3)を格納するローカル変数のみ、3)複数の引数を渡すことはできません代理人なので、ローカルではなく 'HttpClientクライアント'を静的にする必要があります。非同期/待機ウェイは、次のような場合にのみ実際に優れています。 2)、複数の並列タスクが必要ですが、それらを別々に処理する必要はありません(それらを完全に処理する必要があるだけです)。
どのような並列タスクも互いに依存せず、それらを別々に処理する必要がある場合、async/await構文の利点はありますか?
ハンマーよりもハンマーハンマーが優れていますか?状況によって異なります。タスクはスレッドではないことを忘れないでください。 https://blogs.msdn.microsoft.com/benwilli/2015/09/10/tasks-are-still-not-threads-and-async-is-not-parallel/ – TyCobb
投稿を編集して具体的にお尋ねください質問。あなたが達成したいことは非常に不明です...現在、あなたは不正な(スレッドセーフではない)コードを、いくつかの非同期タスクへの順次呼び出しと並行して実行されるスレッドと比較しています。そして、タスクを実行する理由はないと主張します。 –
並行スレッドと非同期処理を待っているのは別のものです。あなたは正確に何を比較していますか? – David