Как в C# не забыть про ConfigureAwait(false)?
Когда пишешь библиотечный async-код, часто встречается такой вариант:
var json = await httpClient.GetStringAsync(url);
return JsonSerializer.Deserialize(json);
Для приложения это обычно нормально. Но для библиотек и низкоуровневого кода часто лучше явно сказать, после await не нужно возвращаться в исходный context.
Для этого используют ConfigureAwait(false):
var json = await httpClient
.GetStringAsync(url)
.ConfigureAwait(false);
После await продолжение может выполниться на любом подходящем потоке:
return JsonSerializer.Deserialize(json);
Это особенно полезно в shared-библиотеках, SDK, инфраструктурном коде и клиентах к внешним API.
Например:
public async Task LoadUserAsync(string id)
{
var response = await client.GetAsync($"/users/{id}")
.ConfigureAwait(false);
return await ParseAsync(response)
.ConfigureAwait(false);
}
Но в UI-коде всё иначе. Если после await нужно обновить интерфейс, context может быть нужен:
label.Text = "Loaded";
В таком случае ConfigureAwait(false) может увести продолжение с UI-потока.
➡️ C# Ready | #совет
Когда пишешь библиотечный async-код, часто встречается такой вариант:
var json = await httpClient.GetStringAsync(url);
return JsonSerializer.Deserialize(json);
Для приложения это обычно нормально. Но для библиотек и низкоуровневого кода часто лучше явно сказать, после await не нужно возвращаться в исходный context.
Для этого используют ConfigureAwait(false):
var json = await httpClient
.GetStringAsync(url)
.ConfigureAwait(false);
После await продолжение может выполниться на любом подходящем потоке:
return JsonSerializer.Deserialize(json);
Это особенно полезно в shared-библиотеках, SDK, инфраструктурном коде и клиентах к внешним API.
Например:
public async Task LoadUserAsync(string id)
{
var response = await client.GetAsync($"/users/{id}")
.ConfigureAwait(false);
return await ParseAsync(response)
.ConfigureAwait(false);
}
Но в UI-коде всё иначе. Если после await нужно обновить интерфейс, context может быть нужен:
label.Text = "Loaded";
В таком случае ConfigureAwait(false) может увести продолжение с UI-потока.
➡️ C# Ready | #совет