2014-12-17 4 views
1

Имеет ли этот код смысл?Async только с одним ожиданием

async Task DoSomething() { 
    await service.doSomething(); 
} 

Это похоже на это?

Task DoSomething() { 
    return service.doSomething(); 
} 

ИЛИ это то же самое с этим?

void DoSomething() { 
    service.doSomething().Wait(); 
} 

Какой код является лучшим в этом случае?

+0

http://stackoverflow.com/questions/9519414/whats-the-difference-between-task-start-wait-and-async-await –

+0

On * which * сценарий? – dcastro

ответ

4

Ваш первоначальный пример:

async Task DoSomething() 
{ 
    await service.doSomething(); 
} 

Есть немного более неэффективна версия, чем ваша первой альтернатива:

Task DoSomething() 
{ 
    return service.doSomething(); 
} 

Это дороже, потому что он должен создать всю государственную машину, связанную с асинхронным кодом, тогда как версия, показанная выше, не требует этого. Если вы должны использовать дизассемблер, такой как IlSpy, и проверить генерируемые компилятором символы, вы увидите, что создается специальный класс для вашей версии async (DoSomething<d__0> или некоторые такие), которые не будут созданы, если вы не использовали async.

С другой стороны, следует избегать, по возможности, вашего второго примера - с использованием .Wait(). Это иллюстрирует две проблем:

  • Использование .Wait означает, что вы выбираете отказ от async, которая побеждает все точки. («Асинхронный» код теперь вызывается в вызывающем потоке и блоках)
  • Использование .Wait также часто приводит к взаимоблокировкам потоков, которые лучше всего разрешать, позволяя использовать семантику await для распространения через ваш код.
+0

Но первый пример не обязательно неверен? это просто неопределенно? –

+2

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

+2

Я думаю, что также уместно указать, что, когда 'SynchronizationContext.Current' не' null', первый фрагмент кода (с 'await', но не' ConfigureAwait (false) ') вводит возможность взаимоблокировки (если блокировка вызывающего объекта на завершенном возврате 'Task'), где раньше не было ничего. Это само по себе является достаточно хорошей причиной, чтобы держаться подальше от 'async/await', где он иначе не добавляет никакой ценности. –

Смежные вопросы