C# ManualResetEvent与解锁有关的行为不一致
我目前面临的问题是,尽管设置了ManualResetEvent,但有时等待的线程不会继续 在ClassA中,我得到了以下代码片段:C# ManualResetEvent与解锁有关的行为不一致,c#,multithreading,C#,Multithreading,我目前面临的问题是,尽管设置了ManualResetEvent,但有时等待的线程不会继续 在ClassA中,我得到了以下代码片段: private ManualResetEvent readyEvent = new ManualResetEvent(false); public async Task Run(CancellationToken cancellationToken) { try { await RunAt(...); readyEv
private ManualResetEvent readyEvent = new ManualResetEvent(false);
public async Task Run(CancellationToken cancellationToken)
{
try
{
await RunAt(...);
readyEvent.Reset();
}
catch (Exception e)
{
var onRequiresRestartEvent = RequiresRestartEvent;
if (onRequiresRestartEvent != null)
{
ThreadPool.QueueUserWorkItem(obj=>onRequiresRestartEvent(this,
EventArgs.Empty));
}
}
}
private IEnumerable<string> ListStuff(Match match)
{
// Do some stuff
readyEvent.Set();
}
我在ClassA.ListStuff上设置了一个断点,readyEvent.Set()确实被执行了,但由于某种原因,程序的执行没有通过ClassB中的.WaitOne
这个代码有什么明显的错误吗?如果没有,我可以采取什么步骤来调试此问题 类A和类B是如何实例化的?在第二部分中,classA似乎是ClassB的一个字段。您确定Set和WaitOne是在ManualResetEvent的同一个实例上执行的吗?这可能是一个愚蠢的问题,但您为什么要将
ManualResetEvent
与await
/异步代码一起使用?在任何情况下,为什么要在运行中调用readyEvent.Reset()
?这会从事件中删除“ready”标志,可能会导致您的问题-如果我没有弄错,如果重置发生在另一个线程有机会执行之前,它可能根本不会得到信号…@Luaan。我在线程方面绝对是个呆子,我这里的代码是遗留代码。所以,你的问题一点也不愚蠢。我将尝试调查您的观点,看看结果如何。@PashaPash ClassB在单元测试中实例化,而ClassA在ClassB中实例化。关于第二个问题,我如何判断Set和WaitOne是否在ManualResetEvent的同一个实例上执行?我模糊地记得,当ManualResetEvents由不同的线程设置时,与ManualResetEvents有关的问题与创建它们的线程不同。
public override void WaitUntilReady(int timeoutMilliseconds)
{
if (!classA.ReadyEvent.WaitOne(timeoutMilliseconds)) // wait
{
throw new TimeoutException("Timeout waiting for the modem");
}
classA.ReadyEvent.Reset();
}