Асинхронизация при продолжении в другом потоке
Я знаю, что Задача может продолжить выполнение в другом потоке, что подтверждается этим кодом.
public async Task Test()
{
var id1 = System.Environment.CurrentManagedThreadId;
await Task.Delay(1000);
var id2 = System.Environment.CurrentManagedThreadId;
Console.Write($"First {id1} then {id2}");
}
Я ожидаю, что фреймворк будет обрабатывать ограничения памяти, так что id1 будет виден при доступе в последнем утверждении.
Но что, если вы используете какой-то фреймворк, например NHibernate, где ISession не является поточно-ориентированным. Фреймворки могут даже проверить, что идентификатор потока все тот же. Как это смешивать?
При создании веб-сайта я буду использовать контейнер IOC с вложенным контейнером для каждого запроса, но когда поток может измениться в рамках одного запроса, не приведет ли это ко всем видам проблем? ThreadStatic не будет работать должным образом
1 ответ
Отсутствие поточной безопасности обычно означает, что не следует использовать его из нескольких потоков одновременно, а не использовать его из одного потока, а затем из другого потока позже.
Я не знаю конкретно о NHibernate, но если это проблема, подумайте об использовании EF Core.
В целом, при использовании асинхронного режима не используйте переменные, привязанные к конкретным потокам, например локальные или статические потоки
Тем не менее, локальные переменные, члены класса, контексты логического вызова, HttpContext
если вы на asp.net и т.д. продолжайте работать. Если у вас есть что-то, что будет потеряно после await
обычно вы можете сначала сохранить его в локальной переменной.
По умолчанию ConfigureAwait(true)
также восстанавливает некоторый контекст продолжения, но может быть трудно понять, что восстанавливается, а что нет. Более поздние версии.net справляются с этой задачей лучше, например, восстановление культуры, чтобы ресурсы продолжали работать после await
,
Здесь есть хорошая статья Стивена Тауба: https://blogs.msdn.microsoft.com/pfxteam/2012/06/15/executioncontext-vs-synchronizationcontext/