c#线程同步 - AutoResetEvent

时间:2011-02-12 12:02:35

标签: c# .net multithreading

我一直在使用AutoResetEvent在线程之间进行同步。

  • 某些线程(A-F)调用autoresetevent.WaitOne();在等待另一个线程(X)完成其工作时
  • 虽然拥有autoresetevent的线程(X)执行其工作,然后调用.Set();

但是只有一个等待线程(A-F)被解除阻塞。 - 当线程(X)完成它的工作时,如何让它们全部解锁?

我想我正在使用错误的同步原语 - 我应该使用什么以及如何使用?

代码示例是理想的

3 个答案:

答案 0 :(得分:4)

ManualResetEvent您要找的是什么?

它将保持设置,直到被某个线程重置为止。

在代码中的某个位置,您必须知道何时重置它。这可能是一个简单的计数器或衍生线程的集合。

答案 1 :(得分:3)

假设您有以下代码:

class Program
{
    static void Main(string[] args)
    {
        var are = new AutoResetEvent(false);

        for (int i = 0; i < 10; i++)
        {
            var j = i;
            new Thread(() =>
            {
                Console.WriteLine("Started {0}", j);
                are.WaitOne();
                Console.WriteLine("Continued {0}", j); 
            }).Start();
        }

        are.Set();

        Console.ReadLine();
    }
}

然后你会得到这样的输出:

Started 0
Started 1
Started 2
Started 3
Started 4
Started 5
Started 6
Started 7
Started 8
Continued 0
Started 9

但是如果您改为使用ManualResetEvent

class Program
{
    static void Main(string[] args)
    {
        var mre = new ManualResetEvent(false);

        for (int i = 0; i < 10; i++)
        {
            var j = i;
            new Thread(() =>
            {
                Console.WriteLine("Started {0}", j);
                mre.WaitOne();
                Console.WriteLine("Continued {0}", j); 
            }).Start();
        }

        mre.Set();

        Console.ReadLine();
    }
}

然后你会得到我猜的预期行为:

Started 0
Started 1
Started 2
Started 3
Started 4
Started 5
Started 6
Started 7
Started 8
Started 9
Continued 1
Continued 8
Continued 7
Continued 4
Continued 5
Continued 6
Continued 3
Continued 0
Continued 9
Continued 2

当然,顾名思义,ManualResetEvent需要手动重置,而AutoResetEvent 自动在第一个{{1>后重置已释放其线程。

答案 2 :(得分:0)

使用System.Threading.ManualResetEvent。

线程A-F调用mre.WaitOne()以等待线程(X)。

当线程X完成时,调用mre.Set()将唤醒线程A-F。

在主题X中,通过执行mre.Reset()将您的mre重置为基本状态。