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