Task.Delay или Thread.Sleep, чтобы приостановить выполнение в методе синхронизации - PullRequest
0 голосов
/ 21 мая 2019

Я хочу приостановить метод синхронизации. Я знаю, что могу использовать:

// SAMPLE 01
Thread.Sleep(30 * 1000)

но он имеет недостаток блокировки текущего потока. Альтернатива

// SAMPLE 02
await Task.Delay(30 * 1000)

будет работать только в асинхронном методе. Но мне нужно это в методе sync . Мы не можем сделать это так

// SAMPLE 03
Task.Delay(30 * 1000).Wait()

потому что это может вызвать тупик (по крайней мере, я так думаю). Мое окончательное решение -

// SAMPLE 04
Task.Run(() => Task.Delay(30 * 1000)).Wait();

Наконец, мой вопрос: действительно ли это решение ( SAMPLE 04 ) лучше, чем SAMPLE 01 (с использованием Thread.Sleep)?

Бонусный вопрос: SAMPLE 03 действительно можно сделать тупик? Что если мы сделаем это:

// SAMPLE 05
Task.Delay(30 * 1000).Wait(30 * 1000)

1 Ответ

2 голосов
/ 21 мая 2019

Действительно ли это решение (SAMPLE 04) действительно лучше, чем SAMPLE 01 (с использованием Thread.Sleep)?

Нет. Это хуже Образец 01 более понятен и эффективен.

имеет недостаток блокировки текущего потока.

Это правда, что Thread.Sleep блокирует текущий поток. В асинхронном методе это было бы недостатком.

Мне нужно это в методе синхронизации.

По определению, вы хотите заблокировать текущий поток. Вот что значит синхронный.

И на самом деле, все ваши примеры do блокируют вызывающий поток (кроме 02, который является асинхронным). Wait блокирует вызывающий поток точно так же, как Thread.Sleep.

SAMPLE 03 действительно может зайти в тупик?

Нет. Чтобы зайти в тупик, вам нужны две разные вещи, которые ждут друг друга, прежде чем они смогут продолжить. Для классического тупика синхронизации по асинхронности ваши две вещи:

  1. Метод async, чей await захватил однопоточный контекст.
  2. Поток заблокирован в этом же контексте.

В вашем примере у вас заблокирована тема. Давайте предположим, что есть однопоточный контекст, и поток заблокирован в этом контексте. У вас все еще не было бы тупика, потому что метод Task.Delay не захватывает его контекст. Так что тупика не будет.

...