Сброс поля, лениво загруженного идиомой перепроверки

Когда вы делаете async / await, вы в основном хотите, чтобы все (большинство) ваших методов работали в async / await. На данный момент вы смешиваете асинхронные и не асинхронные вызовы методов. Это называется блокировкой в ​​контексте async, и его следует избегать , не в последнюю очередь из-за того, что это может привести к тупикам. Я бы посоветовал вам прочитать Async / Await - Best Practices в асинхронном программировании

В целом (и для некоторого упрощения проблемы) все ваши методы должны иметь подпись

public async Task method()
{

}

и всех , которые должны вызываться вашими методами:

await method();

Вот несколько вещей, которые вы делаете неправильно

private async void startDistanceMonitoring()

Никогда не используйте async void (это только для асинхронных обработчиков событий)

private void Sleep(int NoOfMs)
{
    Task.Delay(NoOfMs).Wait();
}

это блокировка, это должно быть

private async Task Sleep(int NoOfMs)
{
    await Task.Delay(NoOfMs);
}

Когда вы звоните:

[ 115]

startDistanceMonitoring - это метод async, но вы его не ожидаете. Так что ваша программа может очень хорошо завершиться, прежде чем она будет завершена. Это должно быть:

await startDistanceMonitoring();

Вы делаете это неправильно во всем этом блоке кода. Всегда вызывайте методы async с await .

Ваш метод ввода не async, public void Run(IBackgroundTaskInstance taskInstance) должен быть public async Task Run(IBackgroundTaskInstance taskInstance)

5
задан GingerPlusPlus 13 February 2016 в 16:46
поделиться

4 ответа

Да, это ориентировано на многопотоковое исполнение.

Синхронизируемый блок должен предотвратить несколько потоков от ненужного вызова computeFieldValue(). С тех пор field энергозависимо, доступы в reset и getField все упорядочены.

Если первая проверка является непустой, getField сделан; result возвращается.

Иначе блокировка получена, исключая любой другой поток, который мог бы установить поле на непустой указатель, но разрешающий любой поток установить field к пустому указателю. Если поток действительно устанавливает field к пустому указателю ничто не должно было изменяться; это - условие, которое получило поток в синхронизируемый блок. Если другой поток уже получил блокировку после проверки текущего потока и установил поле на ненулевое значение, вторая проверка обнаружит это.

4
ответ дан 14 December 2019 в 09:03
поделиться

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

3
ответ дан 14 December 2019 в 09:03
поделиться

Кажется, что это будет работать, пока метод сброса reset() метод упоминается выше. Однако, если reset() метод инстанцирует нового Объекта (как ниже), разве Вы не могли закончить тем потенциально, что возвратили что-то другое, чем Вы предназначили?

void reset() {
    field = new FieldType();
}
0
ответ дан 14 December 2019 в 09:03
поделиться

Я предполагаю, что это зависит от точно, под чем Вы подразумеваете ориентированный на многопотоковое исполнение.

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

0
ответ дан 14 December 2019 в 09:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: