我有一个名为Wait()
的方法,它执行一个长时间运行的工作。它是同步的(它会阻止线程直到操作完成)
我想编写一个Foo()
方法来实现以下逻辑:
调用Foo()方法的第一个线程应该调用
Wait()
如果另一个线程在Wait()方法调用一次后调用Foo()(并且还没有返回),它应该等待/阻塞,直到初始Wait()
调用完成。
我写了以下代码,但我不确定它是否是线程安全的。也许有更好的方法。
我还尝试使用Monitor.Pulse()
/ Monitor.Wait()
来实现逻辑,但是没有成功。
void Foo()
{
if (Monitor.TryEnter(mylock))
{
try
{
Wait();
}
finally
{
Monitor.Exit(mylock);
}
}
else
{
lock(mylock) {}
}
}
答案 0 :(得分:0)
使用共享整数来指示生成和共享布尔值,以指示线程是否在Wait
中被阻止。
布尔值跟踪另一个线程是否要调用wait。如果它是true
,那么我们只需等待(释放监视器),直到其他线程从等待返回。我们知道这是因为它增加了共享整数。如果它是false
,那么我们必须调用wait函数。为了让其他线程(如果有的话)知道等待返回,我们递增共享整数并对它们进行脉冲。
这是逻辑:
true
,请转到步骤12。true
。Wait
函数。false
。PulseAll
Wait
。答案 1 :(得分:0)
这可以通过信号量轻松完成,你只需要等待0的超时,如果它没有等待你去其他地方,你等到它发出信号。
SemaphoreSlim _semaphore = ...
void Foo()
{
try
{
if (_semaphore.Wait(0))
{
Wait();
}
else
{
_semaphore.Wait()
}
}
finally
{
_semaphore.Release();
}
}