これらのDoCalculationメソッドのいずれかが他のものよりもはるかに高速(40%高速)の理由を教えてもらえますか?マルチスレッドパフォーマンスの向上
Iを設定するManualResetEvents待つメインスレッドを持っている:
private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem((obj) =>
{
ManualResetEvent[] finishcalc = new ManualResetEvent[]
{
new ManualResetEvent(false),
new ManualResetEvent(false),
new ManualResetEvent(false),
new ManualResetEvent(false),
new ManualResetEvent(false),
new ManualResetEvent(false)
};
TimeSpan time1 = new TimeSpan(DateTime.Now.Ticks);
DoCalculation(rand.Next(10), rand.Next(10), 1, finishcalc[0]);
DoCalculation(rand.Next(10), rand.Next(10), 2, finishcalc[1]);
DoCalculation(rand.Next(10), rand.Next(10), 3, finishcalc[2]);
DoCalculation(rand.Next(10), rand.Next(10), 4, finishcalc[3]);
DoCalculation(rand.Next(10), rand.Next(10), 5, finishcalc[4]);
DoCalculation(rand.Next(10), rand.Next(10), 6, finishcalc[5]);
if (WaitHandle.WaitAll(finishcalc))
{
TimeSpan time2 =new TimeSpan(DateTime.Now.Ticks);
AddTextAsync(string.Format("DoCalculation Finish in {0}\n" ,(time2-time1).TotalSeconds));
}
});
}
そして私はいくつかの計算を順次実行する別のスレッドを作成する方法を持って、これは私が以前からの結果が必要ですスレッドを使用して次のスレッドを続行します。これを行うには2つの方法があります。これはSilverlight用です。私は新しいスレッドを作成していますし、すべての連続した計算が継続する前に完了することが待って最初の例では
:
void DoCalculation(int number1, int number2, int callid, ManualResetEvent calcdone)
{
ThreadPool.QueueUserWorkItem((obj0) =>
{
AddTextAsync(string.Format("The values for Callid {0} are {1} and {2}\n", callid, number1, number2));
int result = 0;
ManualResetEvent mresetevent = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem((obj) =>
{
result = number1 + number2;
mresetevent.Set();
});
mresetevent.WaitOne();
mresetevent.Reset();
ThreadPool.QueueUserWorkItem((obj2) =>
{
result *= result;
mresetevent.Set();
});
mresetevent.WaitOne();
mresetevent.Reset();
ThreadPool.QueueUserWorkItem((obj2) =>
{
result *= 2;
mresetevent.Set();
});
mresetevent.WaitOne();
AddTextAsync(string.Format("The result for Callid {0} is {1} \n", callid, result));
calcdone.Set();
});
}
DoCalculationの第二の例私はアクションを渡すためにリンクとしてクラスを使用するようにスレッドプールのパラメータとチェーンに第二および第三のスレッドを作成するコールバックとして使用:
リンククラス:
public class CalcParams
{
public int CallID;
public ManualResetEvent ManualReset;
public int Result;
public Action<int, ManualResetEvent, int> CallbackDone;
}
で、Asyの例NCサービス::
public static void DownloadDataInBackground(CalcParams calcparams)
{
WebClient client = new WebClient();
Uri uri = new Uri("http://www.google.com");
client.DownloadStringCompleted += (s, e) =>
{
CalcParams localparams = (CalcParams)e.UserState;
localparams.CallbackDone(e.Result.Length + localparams.Result, localparams.ManualReset, localparams.CallID);
};
client.DownloadStringAsync(uri, calcparams);
}
そして改善doCalculation方法:
void DoCalculation(int number1, int number2, int callid, ManualResetEvent calcdone)
{
ThreadPool.QueueUserWorkItem((obj0) =>
{
int result = number1+number2;
doCalculationService.DownloadDataInBackground(new CalcParams()
{
Result = result,
ManualReset = calcdone,
CallID = callid,
CallbackDone = (r, m, i) =>
{
int sqrt = r * r;
doCalculationService.DownloadDataInBackground(new CalcParams()
{
Result = sqrt,
CallID = i,
ManualReset = m,
CallbackDone = (r2, m2, i2) =>
{
int result2 = r2 * 2;
AddTextAsync(string.Format("The result for Callid {0} is {1} \n", i2, result2));
m2.Set();
}
});
}
});
});
}
はありがとうございます。
StopWatchを使用して、結果を同じにするかどうかに関わらず、時間を測定できますか?また、AddTextAsyncのコードを共有して、おそらくボトルネックがありますか? – sll
私はストップウォッチがSilverlightで利用できないと信じています。私は他のプラットフォームでも同じことをテストできましたが、今はシルバーライトだけに興味があります。そして余計な呼び出しを取り除いても、2つのメソッド間の時間差があまりにも大きいので、なぜわかりません... – montelof
これは、これがコード例です。QueueUserWorkItemがたくさんあります。実際、ハウスキーピングの費用は、あなたがやっている仕事量をはるかに上回っています。 – Skizz