Використовуйте висловлювання та очікуйте, що ключові слова добре зіграють у c


101

У мене виникає ситуація, коли я здійснюю asyncвиклик методу, який повертається та IDisposableекземпляр. Наприклад:

HttpResponseMessage response = await httpClient.GetAsync(new Uri("http://www.google.com"));

Тепер, перш ніж asyncбув на сцені, під час роботи з IDisposableекземпляром цей виклик та код, який використовував змінну "відповідь", будуть загорнуті в оператор, що використовує.

Моє запитання - чи це все-таки правильний підхід, коли asyncключове слово кидається в суміш? Незважаючи на те, що код компілюється, чи використовуватиме оператор, як і очікувалося, в обох прикладах нижче?

Приклад 1

using(HttpResponseMessage response = await httpClient.GetAsync(new Uri("http://www.google.com")))
{
    // Do something with the response

    return true;
}

Приклад 2

using(HttpResponseMessage response = await httpClient.GetAsync(new Uri("http://www.google.com")))
{
    await this.responseLogger.LogResponseAsync(response);

    return true;
}

Відповіді:


97

Так, це повинно бути добре.

У першому випадку ви справді говорите:

  • Асинхронно чекайте, поки ми зможемо отримати відповідь
  • Використовуйте його та негайно утилізуйте

У другому випадку ви говорите:

  • Асинхронно чекайте, поки ми зможемо отримати відповідь
  • Асинхронно чекайте, поки ми не ввійшли у відповідь
  • Утилізуйте відповідь

usingЗаява в методі асинхронному є «непарних» в тому , що Disposeвиклик може виконуватися в іншому потоці до тієї , яка придбала ресурс ( в залежності від контексту синхронізації і т.д.) , але він все одно буде відбуватися ... припускаючи , що ви чекаєте коли-небудь з'являється чи не виходить, звичайно. (Так само, як ви не закінчите дзвонити Disposeв неасинхронний код, якщо ваш usingвислів містить виклик методу, який ніколи не повертається.)


4
Дякую, Джон. Хоча більшість асинхронних речей все ще для мене вуду, це досить заспокійливо бачити, як часто він інтегрується з іншими функціями .net і просто працює
swingdoctor

@JonSkeet Чи варто чекати, навіть якщо він буде використаний всередині using(){...}блоку, або це надмірний рівень або може погіршити продуктивність у деяких випадках? Чи using(){...}служить тій самій цілі, що і await?
нам

1
@nam: Ні, usingі awaitслужить зовсім іншим цілям. Зауважте, що C # 8 також має асинхронне захоронення. Хоча це коштує бути в курсі питання заправної моя відповідь підкреслює, що , безумовно , не означає , що це неправильно змішувати usingі await.
Джон Скіт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.