初めて非同期を見て待っていたとき、それらは非同期プログラミングモデルのC#シンタックスシュガーだったと思います。私は間違っていました、非同期と待機はそれ以上のものです。これはまったく新しい非同期パターンのタスクベースの非同期パターンです。http://www.microsoft.com/en-us/download/details.aspx? id=19957は開始するのに適した記事です。TAPを実装するFCLクラスのほとんどは、APMメソッド(BegingXXX()およびEndXXX())を呼び出します。TAPとAMPの2つのコードスナップは次のとおりです。
TAPサンプル:
static void Main(string[] args)
{
GetResponse();
Console.ReadLine();
}
private static async Task<WebResponse> GetResponse()
{
var webRequest = WebRequest.Create("http://www.google.com");
Task<WebResponse> response = webRequest.GetResponseAsync();
Console.WriteLine(new StreamReader(response.Result.GetResponseStream()).ReadToEnd());
return response.Result;
}
APMサンプル:
static void Main(string[] args)
{
var webRequest = WebRequest.Create("http://www.google.com");
webRequest.BeginGetResponse(EndResponse, webRequest);
Console.ReadLine();
}
static void EndResponse(IAsyncResult result)
{
var webRequest = (WebRequest) result.AsyncState;
var response = webRequest.EndGetResponse(result);
Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd());
}
最後に、GetResponseAsync()がBeginGetResponse()とEndGetResponse()を内部で呼び出すため、これら2つは同じになります。GetResponseAsync()のソースコードを反映すると、次のようなコードが得られます。
task = Task<WebResponse>.Factory.FromAsync(
new Func<AsyncCallback, object, IAsyncResult>(this.BeginGetResponse),
new Func<IAsyncResult, WebResponse>(this.EndGetResponse), null);
APMの場合、BeginXXX()には、タスク(通常はIOの重い操作)が完了したときに呼び出されるコールバックメソッドの引数があります。新しいスレッドを作成して非同期にすると、両方ともすぐにメインスレッドに戻り、両方ともブロックが解除されます。パフォーマンスの面では、ファイルの読み取り、データベース操作、ネットワーク読み取りなどのI / Oバウンド操作を処理するときに、新しいスレッドを作成するとより多くのリソースが必要になります。新しいスレッドを作成することには2つの欠点があります。
- あなたが言及した記事のように、メモリコストがあり、CLRは
スレッドプールの制限です。
- コンテキストスイッチが発生します。一方、非同期は手動でスレッドを作成せず、IOバウンド操作が戻ったときにコンテキストスイッチがありません。
違いを理解するのに役立つ写真を次に示します。
この図は、MSDNの記事「ASP.NET2.0の非同期ページ」からのものであり、ASP.NET2.0で古い非同期がどのように機能するかについて非常に詳細に説明しています。
非同期プログラミングモデルについては、JeffreyRichterの記事「 CLR非同期プログラミングモデルの実装」から詳細を入手してください。また、27章の彼の著書「CLRviaCsharp3rdEdition」にも詳細があります。