在 lock 块内调用异步函数






3.80/5 (4投票s)
在 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();
}
}
});
}