Как описано в моем asyn c intro , метод async
начинает выполняться так же, как и любой другой метод, непосредственно в стеке вызывающего потока. Когда await
действует асинхронно, он захватывает «контекст», «приостанавливает» метод и возвращает его вызывающей стороне. Позже, когда «асинхронное ожидание» (await
) будет завершено, метод будет возобновлен в этом захваченном контексте.
Итак, это означает:
это будет означать, что весь код в методе asyn c будет выполняться в отдельном потоке?
Нет отдельного потока . Никакой поток вообще не «выполняет» await
, потому что ничего не нужно делать. Когда await
завершается, метод продолжает выполняться в этом захваченном контексте. Иногда это означает, что метод помещается в очередь сообщений, где он в конечном итоге будет запущен исходным вызывающим потоком (например, приложения пользовательского интерфейса работают таким образом). В других случаях это означает, что метод выполняется любым доступным потоком пула потоков (большинство других приложений работают таким образом).
Это означает, что вызывающий поток не будет прерван до самого конца (Поток файлов закрыт а метод заканчивается)? Или поток вызывающих будет прерван и go вернется к этому методу, чтобы сначала выполнить интенсивную ЦП часть, а затем go вернуться к тому, что он делал, пока ProcessData () работает в фоновом режиме для части FileStream?
Вызывающий поток никогда не прерывается.
Часть работы, связанная с ЦП, будет выполняться в любом «контексте», захваченном в точке await
. Это может быть исходный поток или поток пула потоков, в зависимости от контекста.
Итак, вернемся к первоначальному вопросу:
Может кто-нибудь сказать мне, что лучший способ сделать это?
Если это код, который можно вызывать из разных контекстов, то я рекомендую не использовать Task.Run
, но я рекомендую документировать, что метод выполняет привязку к процессору Работа. Таким образом, если вызывающая сторона вызывает этот метод из потока пользовательского интерфейса, то она знает, что при вызове его следует использовать Task.Run
, чтобы гарантировать, что поток пользовательского интерфейса не заблокирован.