65.9K
CodeProject 正在变化。 阅读更多。
Home

在 lock 块内调用异步函数

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.80/5 (4投票s)

2016年5月19日

CPOL
viewsIcon

24987

在 lock 块内调用异步函数

为什么?

有时,你可能只想在 lock 语句内执行一个 async 调用。

默认情况下,你无法实现此功能,编译器会对此感到非常恼火,因为你试图在 lock 内创建上下文切换。

我并不是说这是我能想到的最干净的软件设计,但如果你想这样做 – 你可以!

如何

以下是如何解决此问题的方法

在下面的函数中,你可以注意到它们使用了 ManualResetEvent,这使它们能够在 lock 语句内等待,即使存在上下文切换。我们只是在等待事件。

*如果你的 Func 抛出异常,你将无法进入外部 try-catch 块,你需要注意这一点。

代码

public static Task Execute(object lockObject, Func<Task> func)
{
    return Task.Run(() =>
    {
        ManualResetEvent e = new ManualResetEvent(false);
        lock (lockObject)
        {
            bool wait = true;

            func().ContinueWith((taskResult) =>
            {
                wait = false;
                e.Set();
            });

            if (wait)
            {
                e.WaitOne();
            }
        }
    });
}
© . All rights reserved.