我有两个任务Job1和Job2及以下是代码。我第一次按顺序运行Job1和Job2,并将秒表输出设为844毫秒。第二次我评论顺序作业并调用并行任务处理并将秒表结果作为11352毫秒。我的假设/期望是我应该得到输出为422(因为844/2)或接近它的某个地方。但结果完全相反。我需要等待两个作业完成,因此我把t1.Wait()和t2.Wait();请帮助我在一半的顺序处理中处理这两个作业。请在下面找到我的代码:
public ActionResult Index()
{
Stopwatch s = new Stopwatch();
s.Start();
//Execute 2 jobs in a sequence
Job1();
Job2();
//Execute 2 jobs in parallel
//var t1 = Task.Run(() => { Job1(); });
//var t2 = Task.Run(() => { Job2(); });
//t1.Wait();
//t2.Wait();
s.Stop();
Debug.WriteLine("ElapsedMilliseconds: " + s.ElapsedMilliseconds);
return View();
}
private void Job1()
{
for (int i = 0; i < 1000; i++)
{
Debug.WriteLine(i);
}
}
private void Job2()
{
for (int i = 2000; i < 3000; i++)
{
Debug.WriteLine(i);
}
}
答案 0 :(得分:2)
基本上,由于并发期间Debug.WriteLine
的开销,第二个示例会变慢。
如果您删除Debug.WriteLine
(在引擎盖下调用OutputDebugString
),您会注意到一个很大的区别。
MSDN声明:
应用程序应发送非常小的调试输出,并为用户提供启用或禁用其使用的方法。要提供更详细的跟踪,请参阅事件跟踪。
正如伊兰在这里所说:
&#34; if several threads call OutputDebugString concurrently, they will be synchronized&#34; 。
你的第一个例子中没有并发性,这可能是它更快的原因。
您也可以考虑转到单一等待。
从此处更改您的代码:
//Execute 2 jobs in parallel
var t1 = Task.Run(() => { Job1(); });
var t2 = Task.Run(() => { Job2(); });
t1.Wait();
t2.Wait();
......对此:
//Execute 2 jobs in parallel
var tasks = new List<Task>();
tasks.Add(Task.Run(() => { Job1(); }));
tasks.Add(Task.Run(() => { Job2(); }));
Task.WaitAll(tasks.ToArray());
答案 1 :(得分:1)
要理解为什么任务与性能无关,但更多的是响应性,你应该阅读
上下文切换: https://en.wikipedia.org/wiki/Context_switch
处理器使用大量周期切换到另一个线程
Mutexes :https://en.wikipedia.org/wiki/Mutual_exclusion
每次调用Debug.WriteLine时,Task都会等待,直到另一个Task中的Debug.WriteLine完成并执行上下文切换。