如何正确锁定Task.Run()块 [英] How to properly lock a Task.Run() block

查看:44
本文介绍了如何正确锁定Task.Run()块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个应用程序,在其中我使用几种访问某些共享资源的方法,因此通过 lock(thisLock){[...]]

I am writing an application where I use several methods that access to some shared resources, so implemented some safety via 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]});
   }
}

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

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:

private void UpdateStuff()
{

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

我试图获取一些信息,但是我发现的所有内容都提到了使用关键字 async 的情况,而事实并非如此.

I tried to get some information, but everything I found mentions the case when the keyword asyncis used, and this doesn't seems the case.

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

So, my question is: which one is the best/correct way to use a lock() with Task.Run()? Why?

谢谢!

为了明确起见,我的疑问是锁定何时有效以及锁定多少,因此基本上我要问的是,在第一种情况下,是否有可能仅针对 Run()调用,因为该调用本身的内容可能存在于另一个线程中,而在第二种情况下,该锁将与该内容相关联,因此是有效的.

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.

推荐答案

您的第一种方法是完全错误的. Task.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. 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.

这篇关于如何正确锁定Task.Run()块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆