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

Async Task vs async void

Это может быть очень глупый вопрос, но у меня есть следующие строки кодирования, которые конвертируют RAW-изображения в BitmapImages:

public async void CreateImageThumbnails(string imagePath, int imgId)
{
    await Task.Run(() => controlCollection.Where(x => x.ImageId == imgId).FirstOrDefault().ImageSource = ThumbnailCreator.CreateThumbnail(imagePath));
}

который вызывает этот метод CreateThumbnail()

public static BitmapImage CreateThumbnail(string imagePath)
{
    var bitmap = new BitmapImage();

    using (var stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
    {
        bitmap.BeginInit();
        bitmap.DecodePixelWidth = 283;
        bitmap.CacheOption = BitmapCacheOption.OnLoad;
        bitmap.StreamSource = stream;
        bitmap.EndInit();
    }

    bitmap.Freeze();

    GC.WaitForPendingFinalizers();
    GC.Collect();

    return bitmap;
}

При использовании async Void вместо async Task в моем методе CreateImageThumbnails мое приложение обрабатывает изображения (29 из них) примерно на 11 секунд быстрее, чем async Task. Почему это должно быть?

async void async void

задача async async task

Использование памяти намного больше использует void, но операция выполняется намного быстрее. У меня мало знаний о потоковом, вот почему я задаю этот вопрос. Может кто-нибудь объяснить, почему это происходит?

Также я провел некоторое исследование о том, когда и когда не использовать async Void, но я не смог найти ответ на мой вопрос. (Я бы просто не очень хорошо выглядел).

Спасибо.

4b9b3361

Ответ 1

Когда вы вызываете метод async void или вызываете метод async Task, не ожидая его, ваш код будет продолжать работать сразу, не дожидаясь завершения процесса. Это означает, что несколько вызовов метода могут выполняться параллельно, но вы не узнаете, когда они действительно завершатся, что вам обычно нужно знать.

Вы можете воспользоваться параллельным выполнением этого процесса, а также дождаться завершения всех вызовов, сохранив Task в коллекции, а затем используя await Task.WhenAll(tasks);.

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