多等待手柄

时间:2011-07-20 13:03:02

标签: c# multithreading

我的代码如下:

public void MethodA()
{
    MyManualResetEvent.Reset();
}

public void MethodB()
{
    MyManualResetEvent.Set();
}

如果另一个线程调用了MyManualResetEvent.WaitOne()而不是MethodA,则使用MethodB来停止线程时,这是有效的。

我现在要做的是能够两次调用MethodA,只有在MethodB被调用两次时才会继续调用另一个线程,而不是只调用一次。

我希望System.Threading命名空间中有一些我不知道的东西。

3 个答案:

答案 0 :(得分:4)

CountdownEvent可能就是您要找的。 来自MSDN:“表示在计数达到零时发出信号的同步原语。”

http://msdn.microsoft.com/en-us/library/system.threading.countdownevent.aspx

它仅适用于.NET 4.

答案 1 :(得分:3)

假设您不需要停止同时执行的BlockedMethod MethodA即时调用MethodA,这可能最容易通过标准Monitor类来解决。 MethodBMethodA共享一个计数器,该计数器记录了MethodB被调用了多少次而没有相应的BlockedMethod调用。 MethodB方法仅在该计数为0时才进行;如果没有,它等待object mylock = new object(); int count = 0; public void MethodA() { // record that MethodA is executing lock (mylock) count++; // other code... } public void MethodB() { // other code... lock (mylock) { // MethodB has now finished running count--; // wake up other thread because it may now be allowed to run Monitor.Pulse(mylock); } } public void BlockedMethod() { // wait until the number of calls to A and B is equal (i.e., count is 0) lock (mylock) { while (count != 0) Monitor.Wait(mylock); } // calls to A and B are balanced, proceed... } 发出信号表明是时候继续进行了。

{{1}}

答案 2 :(得分:0)

您可以使用System.Threading.Semaphore来执行此类操作。

在一个简单的版本中,这可能看起来像:

    System.Threading.Semaphore s1 = new System.Threading.Semaphore(2, 2);

    public void BeginSomething()
    {
        // This decrements the value of s1.
        s1.WaitOne();
    }

    public void EndSomething()
    {
        // This increments the value of s1.
        s1.Release();
    }

    public void BlockedMethod()
    {
        bool execute = true;
        // Try to get access.
        for (int i = 0; i < 2; i++)
        {
            if (!s1.WaitOne(0))
            {
                for (; i >= 0; i--)
                {
                    s1.Release();
                }
                execute = false;
                break;
            }
        }

        if (execute)
        {
            // This code is only executed if s1 has its starting value 2.

            for (int i = 0; i < 2; i++)
            {
                s1.Release();
            }
        }
    }

但我认为使用这种方式你仍然需要一个信号量来控制函数对的balace。