.NET4.5の初識asyncとawait
7050 ワード
.NET4.0 .NET , 4.0 。 , 5.0 , 。 Web API, , 4.5 , 。async await :
これは2つのキーワードで、非同期プログラミングに使用されます.我々の従来の非同期プログラミング方式は、一般的にThread、ThreadPool、BeginXXX、EndXXXなどである.呼び出し、コールバックを分けて、コードの論理はジャンプして、そこで構想がはっきりしない問題を招くことができます.NET 4.5では、新しく発売されたasync、awaitキーワードは、同期メソッドを書くように非同期メソッドを書くのに役立ちます(コードの整然とした明瞭さを保証します).まず、従来の同期方法の例を見てみましょう.
static void Main(string[] args)
{
//
Console.WriteLine(" !");
SyncMethod(0);
Console.WriteLine(" !");
Console.ReadKey();
}
//
private static void SyncMethod(int input)
{
Console.WriteLine(" !");
var result = SyancWork(input);
Console.WriteLine(" {0}", result);
Console.WriteLine(" !");
}
// ( )
private static int SyancWork(int val)
{
for (int i = 0; i < 5; ++i)
{
Console.WriteLine(" {0}", i);
Thread.Sleep(100);
val++;
}
return val;
}
実行結果は右図から見ることができ、非常に典型的な同期実行方法である.asyncキーワードは、メソッド、lambda式の宣言セクションで使用できます.このメソッドにawaitキーワードが含まれる可能性があることを示すために使用されます.asyncを所有している場合にのみawaitキーワードを内部で使用できます.非同期メソッドは、Task、Task<>またはvoidの戻りタイプを有することができる.awaitキーワードは、戻り値が「待機可能」タイプ(awatable)である方法またはlambda式であり、「awatable」は任意のタイプ(一般的にはTask、Task<>)であり、GetAwaiter()メソッドを開示し、有効な「awater」を返す必要がある.さらに詳しい情報は「AsyncとAwaitのFAQについて」を参考に、これらの概念や注意事項を紹介しています.asyncメソッドがあり、内部にawaitキーワードが含まれている場合、コンパイル時に非同期メソッドとなり、awaitキーワードがない場合、同期メソッドとしてのみ実行されます.内部実装に興味がある場合は、「非同期パフォーマンス:AsyncとAwaitのコストを理解する」を参照してください.このメカニズムを深く理解するのに役立つと信じています.新しい非同期キーワードasync、awaitを使用して、非同期呼び出しに変更してみましょう.
static void Main(string[] args)
{
//
Console.WriteLine("
!");
AsyncMethod(0);
Console.WriteLine(" !");
Console.ReadKey();
}
//
private static async void AsyncMethod(int input)
{
Console.WriteLine(" !");
var result = await AsyncWork(input);
Console.WriteLine(" {0}", result);
Console.WriteLine(" !");
}
// ( )
private static async Task<int> AsyncWork(int val)
{
for (int i = 0; i < 5; ++i)
{
Console.WriteLine(" {0}", i);
await Task.Delay(100);
val++;
}
return val;
}
まず結果を見てみましょう.時間のかかる操作は非同期で行われていることがわかりました.全体的なプロセスは、まずMain関数によってAsyncMethodが非同期で呼び出され、AsyncMethodが完了するのを待たずに、次のように実行されます.一方、AsyncMethod方式は、呼び出された後、タイムスライスに割り当てられた時点で起動を開始し、関数体コンテンツを実行し、await AsyncWork文のためAsyncWorkを非同期で呼び出し続けるが、awaitキーワードのため、ここでAsyncWorkが完了するまで待機してから、引き続き実行する.では、AyncWorkも同様に呼び出された後、タイムスライスに割り当てられた時点で起動を開始し、時間のかかる操作を実行する.新しいキーワードを使用すると,同期と非同期プログラミングの構文の差がさらに減少することがわかる.に従ってNET 4.5の発売により、多くの新しいクラスライブラリと既存のクラスライブラリは、この新しい非同期構文(例えば、HttpClient、HttpServer、MemoryStream...)をサポートしており、これらはReadAsync、WriteAsync、SendAsyncなどの分離方法でasync宣言を提供し、戻りタイプがTask、Task<>の非同期動作を提供している.さっき友达がawait Taskに言及しました.Delay(100)という文は、AsyncWorkを非同期の方法にするために追加されたもので、await修飾をサポートしない場合はどうすればいいのか、簡単です.Taskを使用します.Factory.StartNew()でいいです.例:
//
private static async void AsyncMethod(int input)
{
Console.WriteLine(" !");
var result = await Task.Factory.StartNew((Func<object, int>)SyncWork2, input);
Console.WriteLine(" {0}", result);
Console.WriteLine(" !");
}
// ( )
private static int SyncWork2(object input)
{
int val = (int)input;
for (int i = 0; i < 5; ++i)
{
Console.WriteLine(" {0}", i);
Thread.Sleep(100);
val++;
}
return val;
}
このように,我々のSyncWork 2は実際には非同期で実行され,得られた結果は前の非同期メソッドと一致したが,入力パラメータはobjectタイプのみであり,タイプ変換が必要である.また、StartNewのほかにTaskを新規作成し、Runを呼び出して同じ効果を達成することもできます.現在のところ、このような非同期作業は本人の使用上の不快感をもたらすが、将来のバージョンで、引き続き普及すれば、間もなく熟練し、コードを書くスピードを速め、論理的に明確なコードを書くことができると信じている.