我有一些代码如下:
public void Start()
{
var watch = new Stopwatch();
watch.Start();
Task.Factory.StartNew(MyMethod1);
Task.Factory.StartNew(MyMethod2);
watch.Stop();
Log(watch.ElapsedMilliseconds);
Task.Factory.StartNew(MyMethod3);
}
因为MyMethod1和MyMethod2被异步调用watch.Stop()会在错误的时间被调用。我如何确保在MyMethod1和MyMethod2完成后调用和记录.Stop确保MyMethod3不必等待。
我想在我的Start()方法中保留所有秒表功能,而不是记录我的3种方法中的任何一种,即MyMethod1,MyMethod2和MyMethod3
答案 0 :(得分:20)
您可以使用Task.Factory.ContinueWhenAll
方法。
watch.Start();
var t1 = Task.Factory.StartNew(MyMethod1);
var t2 = Task.Factory.StartNew(MyMethod2);
Task.Factory.ContinueWhenAll(new [] {t1, t2}, tasks => watch.Stop());
如果您的目标是.NET 4.5及更高版本,则还可以使用方法Task.WhenAll
。它返回一个任务,该任务将在所有传递的Task对象完成后完成。
Task.WhenAll(t1, t2).ContinueWith(t => watch.Stop());
答案 1 :(得分:-1)
您需要创建一个新的线程来处理日志记录问题。
此日志记录线程将等待EventWaitHandle.WaitAll(threadsEventWaitHandles)
,其中包含所有线程EventWaitHandles。
这样的事情:
private void LoggingThread()
{
var watch = new Stopwatch();
watch.Start();
EventWaitHandle.WaitAll(threadsEventWaitHandles);
watch.Stop();
Log(watch.ElapsedMilliseconds);
}
并且方法MyMethod1, MyMethod2
将在完成后向登录线程发出信号。
这样的事情:
private void MyMethod1()
{
//... your code
EventWaitHandle.Set();
}
private void MyMethod2()
{
//... your code
EventWaitHandle.Set();
}
因此,您可以确保MyMethod3不必等待。
答案 2 :(得分:-2)
public void Start()
{
var watch = new Stopwatch();
watch.Start();
Task.Factory.StartNew(MyMethod1);
Task.Factory.StartNew(MyMethod2);
Task.WaitAll(); // Wait for previous tasks to finish
watch.Stop();
Log(watch.ElapsedMilliseconds);
Task.Factory.StartNew(MyMethod3);
}