线程和任务调度

时间:2016-01-02 18:28:46

标签: c# multithreading

我有一个通过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被调用与调用它们相同的顺序?

2 个答案:

答案 0 :(得分:3)

如果没有同步机制,则无法保证线程的启动和/或执行顺序。此外,线程的执行可能会在任何时候被抢占(想想:“暂停”)。

所以回答你的问题:

  1. 没有
  2. 没有
  3. 在继续前进之前,你应该问自己“我真的需要使用线程来解决这个问题吗?”

    我最喜欢的微软MSDN引用:

      

    “当您使用任何类型的多线程时,您可能会面临非常严重和复杂的错误”[Best Practices for Implementing the Event-based Asynchronous Pattern]

    如果你确实需要引入线程,那么我首先要熟悉一些微软的同步机制:

答案 1 :(得分:3)

  1. 不,不能保证,你很幸运,每次输出都是一样的。
  2. AutoResetEvent方法的开头添加WaitOne两个任务之间Set的第二个Waiter