Я считаю, что 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
, может быть await
ed - он не обязательно должен быть 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