有人能告訴我爲什麼其中一個DoCalculation方法比另一個快得多(比如快40%)?多線程性能提升
我有等待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));
}
});
}
然後我有一個創建另一個線程做一些計算順序的方法,這就是我需要的結果從以前的線程繼續執行以下操作。我找到了兩種方法來執行此操作,這是針對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的第二個例子傳遞一個作爲行動參數提供給線程池,並用它作爲回調在鏈來創建第二和第三螺紋:
鏈接類:一個ASY的
public class CalcParams
{
public int CallID;
public ManualResetEvent ManualReset;
public int Result;
public Action<int, ManualResetEvent, int> CallbackDone;
}
示例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中不可用..我可以在其他平臺上測試它,但現在我只對silverlight感興趣。而且這兩種方法之間的時間差異太大,甚至刪除額外的呼叫,我不明白爲什麼...... – montelof
我認爲這是示例代碼,裏面有很多QueueUserWorkItem。事實上,家務成本遠遠超過你所做的工作量。 – Skizz