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.
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.
精彩评论