Async await永远锁定线程vs . AsTask(). result
本文关键字:AsTask result vs 线程 await 永远 锁定 Async | 更新日期: 2023-09-27 18:19:20
各位程序员好,我承认我是异步编程的初学者。今天我用异步操作进行了一些测试,发现了一些相当有趣的东西:当我调用await myStorageFolder.GetFilesAsync();
我的异步函数被冻结并且没有抛出任何异常,但是任务永远不会完成,尽管,如果我调用myStorageFolder.GetFilesAsync().AsTask().Result;
,该命令几乎立即返回预期的数据(与winforms Directory.GetFiles()一样快)
现在,我的问题是,写这些行:
var myFileStream = await myFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(myFileStream);
在这种情况下,等待在OpenAsync上工作得很好,但在BitmapDecoder中不行。CreateAsync(冻结),并且,将其转换为Task并调用其"Result"属性并不能使其更快。
所以这是我的问题,什么是最好的方法来解决这个异步编程,调用(await)和(asask ().Result)之间的区别是什么,如果,理论上两者都将在异步线程中"同步"运行?
编辑:下面是我的函数:编辑2:把变量名翻译成英文private async Task ExecuteComparatorAsync(StorageFolder folder)
{
_cancel = false;
Progress = 0;
Status = "Image comparator started.";
List<ImageData> ImagesToCheck = new List<ImageData>();
Status = "Searching Images...";
// if I use await on the next line, the whole function becomes irresponsive and will never return
IReadOnlyList<StorageFile> Files = folder.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.DefaultQuery).AsTask().Result;
Status = "Let me see these images...";
foreach(StorageFile f in Files)
{
try
{
ImageData iData = await GetImageData(f);
ImagesToCheck.Add(iData);
}
catch (Exception s) {
String j = s.Message;
}
}
Status = "Got it.";
List<String> RepetedPaths = new List<String>();
for (int i = 0; i < ImagesToCheck.Count; i++)
{
Status = "Comparing images " + i + "/" + ImagesToCheck.Count;
for (int j = 0; j < ImagesToCheck.Count; j++)
{
if (_cancel)
return;
Boolean IsImageIRepeated = false;
Double Difference = await Compare(ImagesToCheck[i], ImagesToCheck[j]);
if (Difference < MinDiff)
{
String repeatedImage = String.Empty;
if (ImagesToCheck[i].Size > ImagesToCheck[j].Size)
{
repeatedImage = ImagesToCheck[j].Path.Path;
Debug.WriteLine("Duplicate: {0}", ImagesToCheck[j].Path.Path);
}
else
{
IsImageIRepeated = true;
repeatedImage = ImagesToCheck[i].Path.Path;
Debug.WriteLine("Duplicate: {0}", ImagesToCheck[j].Path.Path);
}
RepeatedPaths.Add(repeatedImage);
}
if (IsImageIRepeated)
break;
}
Progress = (i * 100) / ImagesToCheck.Count;
}
Status = String.Format("Done. {0} repeated images found.", Repetidas.Count);
Finished = true;
}
我的主要问题是:
async static Task<WriteableBitmap> LoadImage(StorageFile myFile, UInt32 Width, UInt32 Height)
{
var fStream = await myFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
try
{
// The next line interrupts my entire operation.
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fStream);
// AsTask().Result doesn't work either;
// No exceptions are thrown here.
InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(ras, decoder);
enc.BitmapTransform.ScaledHeight = Height;
enc.BitmapTransform.ScaledWidth = Width;
BitmapBounds bounds = new BitmapBounds();
bounds.Height = Height;
bounds.Width = Width;
bounds.X = 0;
bounds.Y = 0;
enc.BitmapTransform.Bounds = bounds;
try
{
await enc.FlushAsync();
}
catch (Exception ex)
{
string s = ex.ToString();
}
WriteableBitmap bImg = new WriteableBitmap((int)Width, (int)Height);
await bImg.SetSourceAsync(ras);
return bImg;
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
throw new Exception("This file is maybe, not an image at all...");
}
}
由于在某处调用Result
或Wait
而导致死锁的典型案例。审计整个代码以删除对那些容易死锁的函数的调用。或者,以死锁安全的方式调用它们。