【发布时间】:2016-12-22 14:25:27
【问题描述】:
我正在编写一个带有关键区域的应用程序。
我决定使用 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 世界中的线程不太熟悉。
我真的很想了解幕后的真实情况。 感谢您的任何回复;)
【问题讨论】:
-
张贴的 sn-p 不足以证明死锁。但是你做错了是很明显的,把注意力集中在类名上。它是自动重置事件。事件用于信令,“关键区域”需要互斥。这需要一个互斥锁,最容易在 C# 中使用
lock关键字完成。在 UI 线程上使用锁在形式上是非法的,实际上很可能导致死锁。
标签: c# .net multithreading async-await uwp