Skip to main content
 首页 » 编程设计

c#之如何正确锁定 Task.Run() block

2024年02月04日34jpfss

我正在编写一个应用程序,其中我使用多种方法访问一些共享资源,因此通过 lock(thisLock){ [...] ] 实现了一些安全性

一切都很好,直到我不得不在异步任务中使用资源。 这是代码:

private object thisLock = new object(); 
[...] 
private void UpdateStuff() 
{ 
lock(thisLock) 
   { 
     Task.Run(()=>{[code where I use shared resources]}); 
   } 
} 

它似乎工作正常,但我想知道这是否是正确的做法,或者我是否应该将 lock() 部分放在 Run() 中,如下所示:

private void UpdateStuff() 
{ 
 
     Task.Run( () => { 
        lock(thisLock) 
        { 
         [code where I use shared resources] 
        } 
     });     
} 

我试图获取一些信息,但我发现的所有内容都提到了使用关键字 async 时的情况,但似乎并非如此。

所以,我的问题是:哪种方法是将 lock() 与 Task.Run() 一起使用的最佳/正确方法?为什么?

谢谢!

编辑:为了澄清,我怀疑锁何时有效以及锁的有效程度如何,所以基本上我问的是在第一种情况下是否有可能锁仅对 Run( ) 调用,因为调用本身的内容可能存在于另一个线程中,而在第二种情况下,锁将与内容相关联,因此有效。

请您参考如下方法:

您的第一种方法是完全错误的。 Task.Run 可以在同一线程上同步执行工作或将其排队到线程池。您不知道会发生什么。

您不是在等待任务完成,因此如果它排队到线程池,您的函数将释放锁并返回,可能在工作开始之前。

一般来说,最佳做法是只在需要的时间内获取锁,并且永远不要在等待另一个线程时一直持有锁,因为如果你不非常小心,很容易导致死锁。