我在写关键区域的应用程序。AutoResetEvent.WaitOne()导致死锁
我决定使用AutoResetEvent来实现互斥。 下面的代码
public class MyViewModel
{
private AutoResetEvent lock = new AutoResetEvent(true);
private aync Task CriticalRegion()
{
Dosomething();
}
public async Task Button_Click()
{
Debug.WriteLine("Entering Button_Click");
lock.WaitOne();
try
{
await CriticalRegion();
}
finally
{
lock.Set();
Debug.WriteLine("Leaving Button_Click");
}
}
}
我有一个按钮,其单击事件调用Button_Click()
方法
它正常工作。但是,如果我在第一次致电Button_Click()
完成之前再次点击该按钮的时间足够快,则整个应用程序将停止响应。
在调试窗口,我觉得这样的事情
Entering Button_Click
Entering Button_Click
貌似方法永远不会完成。
我挣扎了一下,发现如果我改变lock.WaitOne();
到
if (!sync.WaitOne(TimeSpan.FromSeconds(1)))
{
return;
}
在这种情况下,我的应用程序能够避免僵局,但我不知道为什么它的工作原理。
我只知道我的操作系统课程中的IPC和C#中的async
和await
模式,我对.NET中的线程并不熟悉。
我真的很想了解幕后的真实情况。 感谢您的回信;),直到你调用AutoResetEvent.Set()
,你似乎永远只是后的WaitOne()
呼叫做
张贴的片段不足以证明僵局。但是,你做错了是显而易见的,关注类名。它是自动复位*事件*。事件用于发信号,“关键区域”需要互相排斥。这需要一个互斥锁,最容易在C#中用'lock'关键字完成。在UI线程上使用锁定在形式上是非法的,实际上很可能导致死锁。 –