C# 异步任务与异步void

C# 异步任务与异步void,c#,async-await,task,void,C#,Async Await,Task,Void,这可能是一个非常愚蠢的问题,但我有以下几行代码将原始图像转换为位图图像: public async void CreateImageThumbnails(string imagePath, int imgId) { await Task.Run(() => controlCollection.Where(x => x.ImageId == imgId).FirstOrDefault().ImageSource = ThumbnailCreator.CreateThumbnai

这可能是一个非常愚蠢的问题,但我有以下几行代码将原始图像转换为位图图像:

public async void CreateImageThumbnails(string imagePath, int imgId)
{
    await Task.Run(() => controlCollection.Where(x => x.ImageId == imgId).FirstOrDefault().ImageSource = ThumbnailCreator.CreateThumbnail(imagePath));
}
它调用此方法
create缩略图()

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

异步无效

异步任务

使用
void
,内存使用量要大得多,但操作完成得更快。我对线程知之甚少,这就是为什么我要问这个问题。有人能解释一下为什么会这样吗

我也做了一些关于何时和何时不使用
异步void
的研究,但我找不到我的问题的答案。(我可能只是找得不太好)


谢谢。

当您调用
异步void
方法,或在不等待的情况下调用
异步任务
方法时(如果被调用的方法包含
等待
,因此不会阻塞),您的代码将立即继续,而不会等待该方法实际完成。这意味着该方法的多个调用可以并行执行,但您不知道它们实际何时完成,这通常是您需要知道的

通过将
Task
s存储在一个集合中,然后使用
wait Task.whalll(tasks),您可以利用这样的并行执行,同时还可以等待所有调用完成


还要记住,如果您想并行执行代码,您必须确保这样做是安全的。这通常被称为“线程安全”。

也许这会有所帮助:
async void
是一种“触发并忘记”的方法,因此没有任何东西可以跟踪异步操作(甚至确保它完全运行),而
异步任务
实际上可以跟踪可以等待的内容。@Magnus Yes,当我使用
Task
调用
CreateImageThumbnails
时,我会等待它。如果您不等待它,它将与使用void相同。与问题无关,但请记住
FirstOrDefault()
如果在
controlCollection
中找不到匹配项,则可能引发
NullReferenceException
。如果您确信不会发生这种情况,您仍然可以通过调用
controlCollection.First(x=>x.ImageId==imgId).ImageSource=…
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;
}