2

我有以下方法,我传递了一个加载了 JPEG 数据的 InMemoryRandomAccessStream:

private async Task<byte[]> GetDataAsync(IRandomAccessStream stream)
{
    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);

    BitmapFrame frame = await decoder.GetFrameAsync(0);

    BitmapTransform transform = new BitmapTransform()
    {
        ScaledWidth = decoder.PixelWidth,
        ScaledHeight = decoder.PixelHeight
    };

    PixelDataProvider pixelData = await frame.GetPixelDataAsync(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.DoNotColorManage);

    return pixelData.DetachPixelData();
}

此方法一直挂起,除非我在第一行设置断点并跨过每一行。我尝试使用不同的 JPEG 图像,修改“GetPixelDataAsync”的参数并在行之间临时插入“await Task.Delay(...)”,但没有任何帮助。该应用程序执行许多其他耗时的异步操作,并且除了这部分之外工作正常。目前尚不清楚为什么设置断点(除了它会产生一些时间延迟)使其工作。

请帮助解决这个问题。

4

1 回答 1

2

我猜在野外,但我遇到了同样的问题

我认为您从同步上下文中调用此异步方法,例如:

private void ButtonClick(...) 
{
  var bytes = GetDataAsync(...);
}

这将导致您的应用程序在导致死锁的 UI 线程中运行。要么使调用方法也异步,这将起作用,要么使用 ConfigureAwait(false):

private async Task<byte[]> GetDataAsync(IRandomAccessStream stream)
{
    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream).AsTask().ConfigureAwait(false);

    BitmapFrame frame = await decoder.GetFrameAsync(0).AsTask().ConfigureAwait(false);

    BitmapTransform transform = new BitmapTransform()
    {
        ScaledWidth = decoder.PixelWidth,
        ScaledHeight = decoder.PixelHeight
    };

    PixelDataProvider pixelData = await frame.GetPixelDataAsync(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.DoNotColorManage).AsTask().ConfigureAwait(false);

    return pixelData.DetachPixelData();
}

也许在这里看看这个关于使用 async/await 和获取死锁的非常好的解释

于 2012-09-23T06:38:04.093 回答