Почему Async Await C# использует потоки ThreadPool, когда везде написано «Нет потоков» [закрыто]C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Почему Async Await C# использует потоки ThreadPool, когда везде написано «Нет потоков» [закрыто]

Сообщение Anonymous »

У меня есть серьезные сомнения по поводу того, как async await,configureAwait, Synchronization Context, Task и Threads работают вместе.
AFAIK,
  • Task , Task< TResult >обозначает обещание асинхронной операции.
  • async await не блокирует вызывающий поток и не запускает асинхронный метод синхронно, но вызывающий поток освобождается с этого момента и, следовательно, взамен требуется обещание, заключающее его в Task или Task< TResult >, чтобы оно могло выполнить другую операцию. Преимущество здесь в том, что поток пользовательского интерфейса может выполнять другую работу.
  • Контекст синхронизации — это оркестратор, который ведет учет потоков, которые необходимо вызвать для продолжения после завершения асинхронной операции, и он выполняет множество другие вещи . Я просто буду краток.
  • ConfigureAwait(true) заставляет вызывающий поток ждать, пока асинхронная операция не завершится; false делает ее бесплатной
  • Наконец во всех SO и других популярных блогах, которые async await не создают/не используют потоки пула потоков. Если быть точным, потоки не задействованы.
Я знаю, что контекст синхронизации для приложения WPF — это пользовательский интерфейс, приложение Aspnet — это контекст запроса, а ядро ​​aspnet — контекста нет, в основном потоки пула потоков будут выполнять все асинхронные операции. Для консольного приложения — ThreadPool Thread.

Код: Выделить всё

 public class ValuesController : ApiController
{
// GET api/values
public async Task Get()
{
Debug.WriteLine($"Controller : {Thread.CurrentThread.ManagedThreadId} ThreadId");
var res = await SomeAsyncOperation().ConfigureAwait(true);
Debug.WriteLine($"Controller : {Thread.CurrentThread.ManagedThreadId} ThreadId");
return res;
}

private async Task SomeAsyncOperation()
{
Debug.WriteLine($"SomeAsyncOperation 1: {Thread.CurrentThread.ManagedThreadId} ThreadId");
var re = await SomeOther2AsyncOp().ConfigureAwait(true);
Debug.WriteLine($"SomeAsyncOperation 2: {Thread.CurrentThread.ManagedThreadId} ThreadId");
await Task.Delay(1000).ConfigureAwait(true);
Debug.WriteLine($"SomeAsyncOperation 3: {Thread.CurrentThread.ManagedThreadId} ThreadId");
return re.ToString().ToLower();
}

private async Task SomeOther2AsyncOp()
{
Debug.WriteLine($"SomeAsyncOperation2 1: {Thread.CurrentThread.ManagedThreadId} ThreadId");
await Task.Delay(1000).ConfigureAwait(true);
Debug.WriteLine($"SomeAsyncOperation2 2: {Thread.CurrentThread.ManagedThreadId} ThreadId");
return "Hello";
}
}
Вот результат

Код: Выделить всё

Controller : 11 ThreadId
SomeAsyncOperation 1: 11 ThreadId
SomeAsyncOperation2 1: 11 ThreadId
SomeAsyncOperation2 2: 12 ThreadId
SomeAsyncOperation 2: 12 ThreadId
SomeAsyncOperation 3: 12 ThreadId
Controller : 12 ThreadId

Как вы все можете видеть, он использует потоки пула потоков.
Несколько вопросов
  • Использование потоков ThreadPool имеет смысл потому что какой-то работник должен вернуть значение из асинхронной операции, как только ожидание получит результат. Тогда почему все говорят «Нет потоков»?
  • Я использовал ConfigurationAwait(true) Тогда я предполагал это будет использовать тот же поток, который запустил контекст запроса, чтобы завершить запрос и отправить ответ обратно. Но здесь не тот случай. ПОЧЕМУ?
  • Почему первое переключение контекста происходит в SomeOther2AsyncOp(), а не в SomeAsyncOperation(), потому что async await создает конечный автомат из двух частей: одну до await и другую после await. Достаточно ли компилятор умен, чтобы проверить кодовую базу и настроенный конечный автомат?
  • Aspnet Core не имеет контекста синхронизации, поэтому означает ли это, что все операции асинхронного ожидания будут использовать потоки пула потоков, т.е. 1 контекст переключаться для каждого метода? В этом случае производительность улучшается, потому что один запрос будет потреблять много фоновых потоков.
  • Если я объявлю асинхронность таким образом, например, делегируя единицу работы какому-то работнику и получая уведомление, когда рабочий работа выполнена, это звучит правильно?
Я пытался доказать, что асинхронное ожидание на самом деле использует потоки. Я предоставил фрагмент кода

Подробнее здесь: https://stackoverflow.com/questions/781 ... ts-written
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»