У меня есть серьезные сомнения по поводу того, как 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.
Как вы все можете видеть, он использует потоки пула потоков.
Несколько вопросов
Использование потоков ThreadPool имеет смысл потому что какой-то работник должен вернуть значение из асинхронной операции, как только ожидание получит результат. Тогда почему все говорят «Нет потоков»?
Я использовал ConfigurationAwait(true) Тогда я предполагал это будет использовать тот же поток, который запустил контекст запроса, чтобы завершить запрос и отправить ответ обратно. Но здесь не тот случай. ПОЧЕМУ?
Почему первое переключение контекста происходит в SomeOther2AsyncOp(), а не в SomeAsyncOperation(), потому что async await создает конечный автомат из двух частей: одну до await и другую после await. Достаточно ли компилятор умен, чтобы проверить кодовую базу и настроенный конечный автомат?
Aspnet Core не имеет контекста синхронизации, поэтому означает ли это, что все операции асинхронного ожидания будут использовать потоки пула потоков, т.е. 1 контекст переключаться для каждого метода? В этом случае производительность улучшается, потому что один запрос будет потреблять много фоновых потоков.
Если я объявлю асинхронность таким образом, например, делегируя единицу работы какому-то работнику и получая уведомление, когда рабочий работа выполнена, это звучит правильно?
Я пытался доказать, что асинхронное ожидание на самом деле использует потоки. Я предоставил фрагмент кода
У меня есть серьезные сомнения по поводу того, как async await,configureAwait, Synchronization Context, Task и Threads работают вместе. AFAIK, [list] [*]Task , Task< TResult >обозначает обещание асинхронной операции. [*]async await не блокирует вызывающий поток и не запускает асинхронный метод синхронно, но вызывающий поток освобождается с этого момента и, следовательно, взамен требуется обещание, заключающее его в Task или Task< TResult >, чтобы оно могло выполнить другую операцию. Преимущество здесь в том, что поток пользовательского интерфейса может выполнять другую работу. [*]Контекст синхронизации — это оркестратор, который ведет учет потоков, которые необходимо вызвать для продолжения после завершения асинхронной операции, и он выполняет множество другие вещи . Я просто буду краток. [*]ConfigureAwait(true) заставляет вызывающий поток ждать, пока асинхронная операция не завершится; false делает ее бесплатной [*]Наконец во всех SO и других популярных блогах, которые async await не создают/не используют потоки пула потоков. Если быть точным, потоки не задействованы. [/list] Я знаю, что контекст синхронизации для приложения WPF — это пользовательский интерфейс, приложение Aspnet — это контекст запроса, а ядро aspnet — контекста нет, в основном потоки пула потоков будут выполнять все асинхронные операции. Для консольного приложения — ThreadPool Thread. [code] 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; }
[/code] Как вы все можете видеть, он использует потоки пула потоков. Несколько вопросов [list] [*]Использование потоков ThreadPool имеет смысл потому что какой-то работник должен вернуть значение из асинхронной операции, как только ожидание получит результат. Тогда почему все говорят «Нет потоков»? [*]Я использовал ConfigurationAwait(true) Тогда я предполагал это будет использовать тот же поток, который запустил контекст запроса, чтобы завершить запрос и отправить ответ обратно. Но здесь не тот случай. ПОЧЕМУ? [*]Почему первое переключение контекста происходит в SomeOther2AsyncOp(), а не в SomeAsyncOperation(), потому что async await создает конечный автомат из двух частей: одну до await и другую после await. Достаточно ли компилятор умен, чтобы проверить кодовую базу и настроенный конечный автомат? [*]Aspnet Core не имеет контекста синхронизации, поэтому означает ли это, что все операции асинхронного ожидания будут использовать потоки пула потоков, т.е. 1 контекст переключаться для каждого метода? В этом случае производительность улучшается, потому что один запрос будет потреблять много фоновых потоков. [*]Если я объявлю асинхронность таким образом, например, делегируя единицу работы какому-то работнику и получая уведомление, когда рабочий работа выполнена, это звучит правильно? [/list] Я пытался доказать, что асинхронное ожидание на самом деле использует потоки. Я предоставил фрагмент кода
Я работаю над проектом ASP .NET Core, где у меня есть классы, управляющие пулом рабочих потоков для выполнения задач, и я использую пул потоков .NET для обработки и выполнения задач по обработке входящих HTTP-запросов....
Я работаю над веб-API .NET Core и столкнулся с проблемами производительности и потенциальными взаимоблокировками при вызове асинхронных методов. Я подозреваю, что использую async и жду неправильно. Ниже приведен код, иллюстрирующий мою проблему:...