[C#の]同期方法は、非同期であり、書き換え
序文
私たちは長い時間がかかるプログラムに遭遇すると、
我々は通常、(例えばBeginReadデータストリームの読み取りなど、EndRead)非同期方式を経由して、それを呼び出し、
そのメソッドが同期されていることができれば、我々はそれを行う書き換えることができます方法はありませんか?
このテーマは、同期(シンク)プログラムは、非同期(非同期)プログラムを書き換える方法を導入することです。
実践的な演習
.NET Frameworkの非同期モデル(APM)は、大まかに2つのカテゴリに分けることができ、
たIAsyncResultベースの非同期モデル、およびイベントベースの非同期モデル、
私たちは、最初に、非常に単純な追加機能を構築し、多くの時間を費やすのThread.sleepシミュレートするためにそれを追加し、
public class Calculator
{
public int Calculate(int a, int b)
{
// 模拟花费大量时间运算
System.Threading.Thread.Sleep(10 * 1000);
return a + b;
}
}
通常在程序中执行此函数时看起来会像这样,程序会卡在这边非常久
Calculator calculator = new Calculator();
// 程序会停在这边很长的时间
int result = calculator.Calculate(1, 2);
次に、どのようにこの機能を書き換えることが可能な非同期モードと呼ばれています
1.書き換えたIAsyncResultベースの非同期モデル
まず、最初のデリゲートの同じ機能の入力と出力を確立する必要があり、
、バージョン3.5が内蔵された後のFunc、今日のパラダイムに直接デリゲートとしてのFuncを使用しているので
//In 2.0, sample, not work
//private delegate int CalculateDelegate(int a,int b);
//CalculateDelegate m_calculateDelegate = new CalculateDelegate(Calculate);
private Func
m_calculateDelegate;
その後、我々は、BeginReadをたどるとBeginCalculateとEndCalculate法に書かれた同じデータ・ストリームのEndReadを読み取ることができ、
public IAsyncResult BeginCalculate(int a, int b)
{
this.m_calculateDelegate = this.Calculate;
return this.m_calculateDelegate.BeginInvoke(a, b, null, null);
}
public int EndCalculate(IAsyncResult asyncResult)
{
return this.m_calculateDelegate.EndInvoke(asyncResult);
}
このように、我々は、プログラムで使用することができ、非同期メソッドにBeginCalculateとEndCalculateを呼び出します
そして、前のプログラムは、他のことをし続けるために、計算することができ、
Calculator calculator = new Calculator();
IAsyncResult asyncResult = calculator.BeginCalculate(1, 2);
// Do something else
int result = calculator.EndCalculate(asyncResult);
2.イベントベースの非同期モデルを書き換えます
Event Based的异步模型,在执行完毕之后会将主控权交还给程序,
不会阻塞目前的Thread,一直到执行完毕之后,才会触发注册的事件。
首先我们建立一个当执行完毕时会触发的事件,并且会传入具有计算结果的EventArgs
public event EventHandler
CalculateFinished;
public class CalculateFinishedEventArgs : EventArgs
{
public int Result { get; private set; }
public CalculateFinishedEventArgs(int result)
{
this.Result = result;
}
}
私たちは、再びプログラムを呼び出すためのCalculateAsync方法を確立している、とスレッドの後に実行をブロックしません。
そしてそれは、トリガ・イベントCalculateFinished後に完成する予定、
public void CalculateAsync(int a, int b)
{
this.m_calculateDelegate = Calculate;
AsyncCallback callback = new AsyncCallback(OnCalculateFinished);
this.m_calculateDelegate.BeginInvoke(a, b, callback, m_calculateDelegate);
}
private void OnCalculateFinished(IAsyncResult asyncResult)
{
Func calculateDelegate = (Func)asyncResult.AsyncState;
int result = calculateDelegate.EndInvoke(asyncResult);
EventHandler temp = CalculateFinished;
if (temp != null)
{
temp(this, new CalculateFinishedEventArgs(result));
}
}
,>,>
プログラムの実行は、のように書き換えることができます
Calculator calculator = new Calculator();
calculator.CalculateFinished += (o, args) => MessageBox.Show(string.Format("Result is {0}", args.Result));
calculator.CalculateAsync(1, 2);
// Do other works...
エピローグ
システムリソース、並列ジョブを効率的に使用するための、および優れたユーザーエクスペリエンスをユーザーに提供し、
非同期メソッド呼び出し書き込みプログラムを使用する場合は、不可欠です
しかし同時に、非同期プログラムを書いてますが、多くの場合、断片的なプログラムになり、
そして、読み、次の記事では、問題を抱え維持しにくく、
状況を改善するためにIteratorを使用する方法を紹介します、
もちろん、非同期呼び出しの前述の方法は、処理ウィンドウの内外に利用することができます、
スレッドまたは処理するためのBackgroundWorkerの方法を通じて、
また、こんにちは^ _ ^議論やアドバイスをたくさんして歓迎します
参考データ:
1. http://msdn.microsoft.com/zh-tw/library/2e08f6yc(v=VS.100).aspx非同期同期メソッドを呼び出します
2. http://msdn.microsoft.com/zh-tw/magazine/cc163467.aspx練習書き込みプログラムの非同期CLRモデル
オリジナル:大カラム 非同期メソッドを書き換える[C#の]同期方法