Как правильно заблокировать блок Task.Run () - PullRequest
1 голос
/ 07 июня 2019

Я пишу приложение, в котором я использую несколько методов доступа к некоторым общим ресурсам, поэтому реализовал некоторую безопасность с помощью 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(), поскольку содержимое самого вызова может находиться в другом потоке, в то время как во втором случае блокировка будет связана с содержимым и, таким образом, будет действовать.

Ответы [ 2 ]

3 голосов
/ 07 июня 2019

Ваш первый подход совершенно неверен. Task.Run может выполнить работу синхронно в том же потоке или поставить ее в очередь в пуле потоков. Вы не знаете, что произойдет.

Вы не ожидаете завершения задачи, поэтому, если она будет поставлена ​​в очередь в пуле потоков, ваша функция снимет блокировку и вернется, возможно, еще до того, как работа будет начата.

В общем, лучшая практика заключается в том, чтобы захватывать блокировки только столько времени, сколько необходимо, и никогда не удерживать блокировку во время ожидания другого потока, поскольку вы можете очень легко получить тупик, если не будете особенно осторожны.

1 голос
/ 07 июня 2019

Между этими двумя способами нет лучшего способа, вы просто получаете 2 разных результата:

В первом случае вы не начнете задание, пока замок не будет открыт.

Во втором случае вы запустите задание, которое ничего не будет делать, пока замок не будет открыт.

По моему мнению, не открывать задачу, пока она вам не нужна, это лучший подход, но это просто личное мнение. Открытие и блокировка после, выделит бесполезные ресурсы.

...