关于C#:不阻塞当前(UI)线程的互斥体

Mutex that not block current(UI) thread

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

Mutex接口:

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

1
2
3
await mutex.Lock();
// critical code  
mutex.Release();

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

1
2
3
4
5
await Task.Factory.StartNew(() =>
{
    mutex.WaitOne();
    UserDispatcher = Dispatcher.CurrentDispatcher;
});

在Release方法中,我执行以下操作:

1
2
3
4
5
6
7
8
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


当UI线程卡住以等待互斥体在mutex.WaitOne();上释放时,您可能手上有死锁,并且您试图通过发布相同的UI线程(已阻止)释放该互斥锁使用调度程序在其上mutex.ReleaseMutex();

如果需要async互斥锁,则可以简单地将SemaphoreSlim设置为1(因此,互斥),然后调用WaitAsync异步等待。

这是我使用SemaphoreSlim实现的AsyncLock(与异步互斥锁相同)。