이러한 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));
}
});
}
가 그럼 난 몇 가지 계산을 순차적으로 수행하는 다른 스레드를 만들 방법이를 본 나는 이전의 결과가 필요하다 thread를 사용하여 다음과 같은 작업을 계속할 수 있습니다. 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의 두 번째 예는 액션을 통과 ThreadPool이 행 변수 및 체인의 두 번째 및 세 번째 스레드를 생성하는 콜백으로 사용
링크 클래스하십시오 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
나는 스톱워치를 실버 라이트에서 사용할 수 없다고 생각한다. 다른 플랫폼에서도 똑같은 것을 테스트 할 수는 있지만 지금은 실버 라이트에만 관심이있다. 그리고 여분의 호출을 제거하는 두 가지 방법간에 너무 많은 시간 차이가 있습니다. 이유는 알 수 없습니다. – montelof
이 예제 코드는 QueueUserWorkItem이 많이 있습니다. 실제로, 관리 비용은 당신이하는 일의 양을 훨씬 초과합니다. – Skizz