Подтвердить что ты не робот

Использует ли использование async/wait новый поток?

Я новичок в TPL, и мне интересно: как поддержка асинхронного программирования, которая является новой для С# 5.0 (через новые async и await ключевые слова) относятся к созданию потоков?

В частности, использует ли async/await новый поток при каждом использовании? И если существует много вложенных методов, которые используют async/await, это новый поток, созданный для каждого из этих методов?

4b9b3361

Ответ 1

Короче NO

Из Асинхронное программирование с использованием Async и Await: Threads

Асинхронные и ожидающие ключевые слова не вызывают дополнительных потоков создано. Асинхронные методы не требуют многопоточности, поскольку асинхронный метод не запускается в своем потоке. Метод работает на текущем синхронизации и использует время в потоке только тогда, когда метод активен. Вы можете использовать Task.Run, чтобы переместить работу, связанную с процессором, на фоновый поток, но фоновый поток не помогает с процессом что просто ждет, когда результаты станут доступными.

Ответ 2

Итак, я ознакомился с моделью потоков, и Async/Await, безусловно, может привести к использованию новых потоков (необязательно созданных - пул создает их при запуске приложения). Это до планировщика, чтобы определить, нужен ли новый поток. И, как я понимаю, вызов ожидаемой функции может иметь внутренние детали, которые увеличивают шансы планировщика использовать другой поток; просто потому, что больше работы означает больше возможностей/причин для планировщика разделять работу.

Асинхронные операции WinRT автоматически выполняются в пуле потоков. И, как правило, вы будете вызывать FROM из пула потоков, за исключением работы потока пользовательского интерфейса. Xaml/Input/Events.

Асинхронные операции, запущенные в потоках Xaml/UI, возвращают свои результаты в [вызывающий] поток пользовательского интерфейса. Но результаты асинхронной операции, запущенные из потока пула потоков, доставляются везде, где происходит завершение, что может быть не тем потоком, в котором вы были раньше. Причиной этого является то, что код, написанный для пула потоков, скорее всего, будет написан для обеспечения безопасности потоков, а также для эффективности. Windows не нужно согласовывать этот переключатель потоков.

Итак, еще раз, в ответ на OP новые потоки не обязательно создаются, но ваше приложение может и будет использовать несколько потоков для выполнения асинхронной работы.

Я знаю, что это, кажется, противоречит некоторым литературным источникам относительно async/await, но это потому, что хотя конструкция async/await сама по себе не является многопоточной. Awaitables - это один из механизмов, с помощью которых планировщик может разделять работу и создавать вызовы между потоками.

На данный момент это предел моих знаний об асинхронности и потоке, поэтому, возможно, я не совсем правильно понял, но я думаю, что важно видеть связь между ожидаемыми и потоками.

Ответ 3

Извините за опоздание на вечеринку.

Я новичок в TPL и мне интересно: как работает асинхронный поддержка программирования, которая является новой для С# 5.0 (через новый async и await ключевые слова) относятся к созданию темы?

async/await не вводится для создания потока, но для оптимального использования текущего потока.

Ваше приложение может читать файлы, ждать ответа от другого сервера или даже выполнять вычисления с высоким доступом к памяти (просто любая задача ввода-вывода). Эти задачи не нагружают процессор (любая задача, которая не будет использовать 100% вашего потока).

Представьте, что вы выполняете 1000 задач, не требующих значительных ресурсов процессора. В этом случае процесс создания тысяч нитей уровня ОС может потреблять больше ресурсов ЦП и памяти, чем выполнение реальной работы в одном потоке (4 МБ на поток в Windows, 4 МБ * 1000 = 4 ГБ). В то же время, если вы выполняете все задачи последовательно, вам, возможно, придется подождать, пока задачи ввода-вывода будут завершены. Которые заканчиваются в течение долгого времени для выполнения задачи, сохраняя при этом процессор бездействующим.

Поскольку для быстрого выполнения нескольких задач нам требуется параллелизм, в то же время все пареллальные задачи не требуют много ресурсов процессора, но создание потоков неэффективно.

Компилятор прервет выполнение при любом вызове метода для метода async (независимо от того, является он awaited или нет) и немедленно выполнит оставшийся код, как только будет достигнут await, выполнение перейдет в предыдущий async. Это будет повторяться снова и снова, пока все асинхронные вызовы не будут завершены и их awaiters не удовлетворены.

Если какой-либо из асинхронных методов имеет большую загрузку ЦП без вызова асинхронного метода, то да, ваша система перестает отвечать на запросы, и все остальные асинхронные методы не будут вызываться до тех пор, пока текущая задача не будет завершена.

Ответ 4

Использование Async/Await не обязательно приводит к созданию нового потока. Но использование Async/Await может привести к созданию нового потока, поскольку ожидаемая функция может внутренне порождать новый поток. И часто это делает утверждение "Нет, это не порождает темы", практически бесполезное на практике. Например, следующий код порождает новые темы.

VisualProcessor.Ctor()
{
    ...
    BuildAsync();
}

async void BuildAsync()
{
    ...
    TextureArray dudeTextures = await TextureArray.FromFilesAsync(…);
}

public static async Task<TextureArray> FromFilesAsync(...)
{    
    Debug.WriteLine("TextureArray.FromFilesAsync() T1 : Thread Id = " + GetCurrentThreadId());
    List<StorageFile> files = new List<StorageFile>();
    foreach (string path in paths)
    {
        if (path != null)
            files.Add(await Package.Current.InstalledLocation.GetFileAsync(path)); // << new threads
        else
            files.Add(null);
    }
    Debug.WriteLine("TextureArray.FromFilesAsync() T2 : Thread Id = " + GetCurrentThreadId());
    ...
}