不阻塞当前(UI)线程的互斥锁

时间:2014-12-07 21:32:03

标签: c# wpf multithreading asynchronous async-await

我有一个小任务 - 我必须创建互斥,使用任务和async \ await,而不是阻止当前线程(UI线程)。

Mutex界面:

Lock() - 返回一个任务,只有当互斥锁变为空闲时才会完成。这项任务必须是 每次锁定唯一,每次Release()调用不允许超过1次取消阻止。 Release() - 释放互斥锁。 Lock()返回的唯一一个任务必须完成。 那个互斥体必须以这种方式工作

await mutex.Lock();
// critical code  
mutex.Release();

我写了一些代码(最后看到链接),但如果简单描述问题是: 我创建了一个Mutex类。 在Lock方法中我做了类似的事情:

await Task.Factory.StartNew(() =>
{
    mutex.WaitOne();
    UserDispatcher = Dispatcher.CurrentDispatcher;
});

在方法发布中我做了类似的事情:

if (mutex != null && UserDispatcher != null)
{
    UserDispatcher.Invoke(new Action(() =>
    {
        Console.WriteLine("Releasing");
        mutex.ReleaseMutex();
    }));
}

当我尝试发布互斥锁时,我的程序会永远冻结。有什么问题?

完整代码:https://www.dropbox.com/s/4a370cn1bd2o0nz/MainWindow.xaml.cs?dl=0

项目链接:https://www.dropbox.com/sh/qsgle79jdgpr7cd/AAA3MZ6VlTNbUj-isgaQaLE-a?dl=0

1 个答案:

答案 0 :(得分:0)

当UI线程卡住等待在mutex.WaitOne();上释放互斥锁并且您尝试通过发布使用相同的UI线程(被阻止)释放它时,您的手上可能会出现死锁使用调度程序在其上mutex.ReleaseMutex();

如果您需要async互斥锁,只需将SemaphoreSlim设置为1(因此,互斥)并调用WaitAsync即可异步等待。

Here使用AsyncLock实现SemaphoreSlim(与异步互斥锁相同)。