Я считаю, что TPL (TaskFactory.Startnew) работает аналогично ThreadPool.QueueUserWorkItem в том, что он ставит в очередь работу над потоком в пуле потоков.
Практически.
Из того, что я читал, кажется, что async / await только «иногда» создает новый поток.
На самом деле, этого никогда не происходит. Если вам нужна многопоточность, вы должны реализовать это самостоятельно. Есть новый метод Task.Run, который является сокращением для Task.Factory.StartNew, и, вероятно, это наиболее распространенный способ запуска задачи в пуле потоков.
Если бы вы имели дело с портами завершения ввода-вывода, я мог бы видеть, что ему не нужно создавать новый поток, но в противном случае я бы подумал, что это придется.
Бинго. Таким образом, такие методы, как Stream.ReadAsync, фактически создают Task оболочку вокруг IOCP (если Stream имеет IOCP).
Вы также можете создавать некоторые «задачи», не связанные с вводом-выводом и не связанные с процессором. Простым примером является Task.Delay, который возвращает задачу, которая завершается через некоторый период времени.
В _7 _ / _ 8_ замечательно то, что вы можете поставить в очередь некоторую работу в пуле потоков (например, Task.Run), выполнить некоторые операции, связанные с вводом-выводом (например, Stream.ReadAsync), и выполнить некоторые другие операции (например, Task.Delay). ... а они все задачи! Их можно дождаться или использовать в комбинациях вроде Task.WhenAll.
Любой метод, который возвращает Task, может быть awaited - он не обязательно должен быть async методом. Таким образом, Task.Delay и операции, связанные с вводом-выводом, просто используют TaskCompletionSource для создания и завершения задачи - единственное, что делается в пуле потоков, - это фактическое завершение задачи при возникновении события (тайм-аут, завершение ввода-вывода и т. Д.).
Я предполагаю, что мое понимание FromCurrentSynchronizationContext всегда было немного нечетким. Я всегда думал, что это, по сути, поток пользовательского интерфейса.
Я написал статью о SynchronizationContext. В большинстве случаев SynchronizationContext.Current:
- - это контекст пользовательского интерфейса, если текущий поток является потоком пользовательского интерфейса.
- - это контекст запроса ASP.NET, если текущий поток обслуживает запрос ASP.NET.
- в противном случае - это контекст пула потоков.
Любой поток может установить свой собственный SynchronizationContext, поэтому есть исключения из правил выше.
Обратите внимание, что ожидающий Task по умолчанию будет планировать оставшуюся часть метода async для текущего SynchronizationContext , если он не равен нулю; иначе идет текущий TaskScheduler. Сегодня это не так важно, но в ближайшем будущем станет важным отличием.
Я написал свое собственное _25 _ / _ 26_ intro в моем блоге, и Стивен Туб недавно опубликовал отличный _27 _ / _ 28_ FAQ.
Что касается «параллелизма» и «многопоточности», см. этот связанный вопрос SO а>. Я бы сказал, что async разрешает параллелизм, который может быть, а может и не быть многопоточным. Легко использовать await Task.WhenAll или await Task.WhenAny для параллельной обработки, и если вы явно не используете пул потоков (например, Task.Run или ConfigureAwait(false)), вы можете одновременно выполнять несколько параллельных операций (например, несколько операций ввода-вывода или другие типа Delay) - и для них не нужен поток. Я использую термин «однопоточный параллелизм» для такого рода сценариев, хотя на хосте ASP.NET вы можете фактически получить «нулевой -поточный параллелизм». Что довольно мило.
person
Stephen Cleary
schedule
23.04.2012
TaskCreationOptions.LongRunning. - person Zaid Masud   schedule 27.02.2013Thread.CurrentThread.IsThreadPoolThreadвозвращал истину для коротких потоков в несколько сотен миллисекунд. не говоря уже о переменных ThreadStatic, которые я использовал для вывода на несколько потоков, что приводило к разного рода хаосу. Мне пришлось заставить свой код обновлять несколько Thread () по старинке, чтобы гарантировать выделенный поток. Другими словами, я не мог использовать TaskFactory для выделенных потоков. При желании вы можете реализовать свой собственныйTaskScheduler, который всегда возвращает выделенный поток. - person eduncan911   schedule 11.03.2013