开发者

Multi Wait handle

I have code such as:

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

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

This works when using MyManualResetEvent.WaitOne() to stop a thread if another thread has called MethodA but not MethodB.

What i want to do now is be able to call MethodA twice, with another thread only continuing if MethodB is called twice, rather than just once.

I'm hoping there's something in the System.Threading namespace 开发者_运维知识库i don't know about.


CountdownEvent may be what you are looking for.

From MSDN: "Represents a synchronization primitive that is signaled when its count reaches zero."

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

It's only available in .NET 4.


Assuming you don't need to stop a concurrently-executing BlockedMethod the instant MethodA is called, this is probably most easily solved with the standard Monitor class. MethodA and MethodB share a counter which records how many times MethodA has been called without a corresponding call to MethodB. The BlockedMethod method only proceeds if that count is 0; if not, it waits for MethodB to signal it that it's time to proceed.

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...
}


You can use a System.Threading.Semaphore to do such things.

In a simple version this could look like:

    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();
            }
        }
    }

But i think using this way you would still need one semaphore to control the balace of a function pair.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜