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...");
        }
    }

Async await永远锁定线程vs . AsTask(). result

由于在某处调用ResultWait而导致死锁的典型案例。审计整个代码以删除对那些容易死锁的函数的调用。或者,以死锁安全的方式调用它们。