异步任务与异步无效

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;
}

在我的 CreateImageThumbnails 方法中使用 async Void 而不是 async Task 时,我的应用程序处理图像(其中 29 个)比 async Task 快大约 11 秒。为什么会这样?

异步无效

异步任务

内存使用量比使用 void 多得多,但操作完成 快。我对线程知之甚少,这就是我问这个问题的原因。有人可以解释为什么会这样吗?

此外,我还对何时以及何时不使用 async void 进行了一些研究,但我找不到问题的答案。 (我可能只是没有很好地搜索)。

谢谢。

当您调用 async void 方法,或调用 async Task 方法而不等待它(如果调用的方法包含 await,则它不会阻塞),您的代码将立即继续,无需等待方法实际完成。这意味着该方法的多个调用可以并行执行,但您不知道它们何时真正完成,而您通常需要知道这一点。

您可以利用像这样并行执行的优势,同时还可以通过Task 存储在集合中 来等待所有调用完成然后使用 await Task.WhenAll(tasks);.

另请记住,如果您想并行执行代码,则必须确保这样做是安全的。这通常称为 "thread-safety"。