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 に答える