【问题标题】:Mutex that not block current(UI) thread不阻塞当前(UI)线程的互斥锁
【发布时间】:2014-12-09 00:33:23
【问题描述】:

我有一个小任务 - 我必须创建互斥锁,使用任务和异步\等待,不阻塞当前线程(UI 线程)。

互斥接口:

Lock() - 返回一个任务,只有当互斥锁变得空闲时才会完成。这个任务必须 每个锁唯一,以禁止每个 Release() 调用超过 1 个解除阻塞。 Release() – 释放互斥锁。 Lock() 返回的一项且唯一一项任务必须完成。 该互斥体必须以这种方式工作

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

我写了一段代码(见最后的链接),但如果简单描述问题是: 我创建了一个类互斥锁。 在方法 Lock 我做这样的事情:

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

在 Release 方法中,我做了类似的事情:

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

【问题讨论】:

    标签: c# wpf multithreading asynchronous async-await


    【解决方案1】:

    当 UI 线程卡住等待在 mutex.WaitOne(); 上释放互斥锁并且您尝试使用相同的 UI 线程(被阻止)通过发布 @ 来释放它时,您可能遇到了死锁987654324@ 使用调度程序就可以了。

    如果您想要一个 async 互斥锁,您可以简单地将 SemaphoreSlim 设置为 1(因此,互斥)并调用 WaitAsync 以异步等待。

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

    【讨论】:

    • 这里有个小问题...我的 Mutex 必须以这种方式工作 await mutex.Lock(); ,我不能用信号量做到这一点(
    • @progerz 你可以使用SemaphoreSlimWaitAsync
    • @i3aron 它会以这种方式工作吗?你有 Skype 或其他信使吗?我对此几乎没有什么疑问。
    • @progerz 会的。你在这个问题上有一个完整的例子:stackoverflow.com/a/21011273/885318。如果您有问题,最好在那里询问,因为每个人都可以看到它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 2012-12-25
    • 2015-05-03
    • 2017-10-06
    • 1970-01-01
    相关资源
    最近更新 更多