简体   繁体   English

如何正确锁定Task.Run()块

[英]How to properly lock a Task.Run() block

I am writing an application where I use several methods that access to some shared resources, so implemented some safety via lock(thisLock){ [...] ] 我正在编写一个应用程序,其中使用了几种访问某些共享资源的方法,因此通过lock(thisLock){ [...] ]实现了一些安全性lock(thisLock){ [...] ]

All was well until I had to use a resources inside an async task. 一切都很好,直到我不得不在异步任务中使用资源。 This is the code: 这是代码:

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

It seems to work fine, but I was wondering if this is the correct way to do, or if I should put the lock() part inside the Run(), like this: 似乎工作正常,但我想知道这是否是正确的方法,还是应该将lock()部分放在Run()内,如下所示:

private void UpdateStuff()
{

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

I tried to get some information, but everything I found mentions the case when the keyword async is used, and this doesn't seems the case. 我试图获取一些信息,但是我发现的所有内容都提到了使用关键字async时的情况,但情况似乎并非如此。

So, my question is: which one is the best/correct way to use a lock() with Task.Run()? 因此,我的问题是:哪一种是与Task.Run()一起使用lock()的最佳/正确方法? Why? 为什么?

Thank you! 谢谢!

EDIT: In order to clarify, my doubt is about when and how much the lock is effective, so basically I am asking if in the first case there is a possibility where the lock is valid just for the Run() call, since the content of the call itself could live in another thread, while in the second case the lock will be associated to the content and so be effective. 编辑:为澄清起见,我的疑问是锁定何时有效以及锁定多少,所以基本上我是在问第一种情况下是否有可能仅对Run()调用有效的锁定,因为内容调用本身可以驻留在另一个线程中,而在第二种情况下,锁将与内容相关联,因此有效。

Your first approach is entirely wrong. 您的第一种方法是完全错误的。 Task.Run can either execute the work synchronously on the same thread or queue it to a thread pool. Task.Run可以在同一线程上同步执行工作,也可以将其排队到线程池中。 You don't know which is going to happen. 您不知道会发生什么。

You aren't waiting for the task to complete, so if it gets queued to a thread pool, your function is going to release the lock and return, potentially before the work has even started. 您不是在等待任务完成,因此,如果将其排队到线程池中,则您的函数可能会在工作开始之前释放锁并返回。

In general, best practice is to only acquire locks for as little time as needed, and never keep a lock held while waiting for another thread, as you can end up with a deadlock very easily if you aren't extremely careful. 通常,最佳实践是仅在需要的时间内获取锁,并且在等待另一个线程时不要保持锁,因为如果您不太谨慎的话,很容易导致死锁。

There isn't a best way between these two, you just obtain 2 different results: 两者之间没有最好的方法,您只能获得两种不同的结果:

In the first case, you won't start a task till the lock is opened. 在第一种情况下,直到打开锁,您才可以启动任务。

In the second case you will start a task which won't do anything till the lock is opened. 在第二种情况下,您将启动一个任务,该任务在打开锁之前不会执行任何操作。

In my opinion not opening a task till you need it, is a better approach, but it's just a personal opinion. 在我看来,直到需要时才打开任务是一种更好的方法,但这只是个人观点。 Opening and locking after, will allocate useless resources. 打开并锁定后,将分配无用的资源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM