我有一个通过AutoResetEvent
基本上有两个线程可以交换控制和执行命令,每次都是一个线程。
代码:
static EventWaitHandle _waitHandle = new AutoResetEvent(false);
static void Waiter()
{
_waitHandle.WaitOne();
Console.WriteLine("A...");
_waitHandle.Set();
_waitHandle.WaitOne();
Console.WriteLine("A2...");
_waitHandle.Set();
}
static void Waiter2()
{
_waitHandle.WaitOne();
Console.WriteLine("B...");
_waitHandle.Set();
_waitHandle.WaitOne();
Console.WriteLine("B2...");
}
void Main()
{
new Thread(Waiter).Start();
new Thread(Waiter2).Start();
_waitHandle.Set(); // Wake up the Waiter.
}
结果 :(我总是得到这个结果)
A...
B...
A2...
B2...
然而 - 当我搬到Tasks
时:
Task.Run(()=>Waiter());
Task.Run(()=>Waiter2());
我有时会得到:
B...
A...
B2...
我很清楚,因为任务调度程序安排第二个任务先执行。
这让我问:
问题
1)线程顺序保证与调用顺序相同:
new Thread(Waiter).Start();
new Thread(Waiter2).Start();
//In other words , will I always get the first result ?
2)如何强制Task.Run
被调用与调用它们相同的顺序?
答案 0 :(得分:3)
如果没有同步机制,则无法保证线程的启动和/或执行顺序。此外,线程的执行可能会在任何时候被抢占(想想:“暂停”)。
所以回答你的问题:
在继续前进之前,你应该问自己“我真的需要使用线程来解决这个问题吗?”
我最喜欢的微软MSDN引用:
“当您使用任何类型的多线程时,您可能会面临非常严重和复杂的错误”[Best Practices for Implementing the Event-based Asynchronous Pattern]
如果你确实需要引入线程,那么我首先要熟悉一些微软的同步机制:
答案 1 :(得分:3)
AutoResetEvent
方法的开头添加WaitOne
两个任务之间Set
的第二个Waiter
。