WinUI3 BitmapEncoder.FlushAsync() 挂起

问题描述 投票:0回答:1

我的 WinUI3 应用程序中有以下代码:

public class Screenshot(byte[] pixels, int width, int height)
{
    public byte[] Pixels { get; } = pixels;
    public int Width { get; } = width;
    public int Height { get; } = height;
}

public static async Task<string> ByteArrayToBase64PNGStringAsync(Screenshot screenshot)
{
    using (InMemoryRandomAccessStream memoryStream = new())
    {
        await RenderPixelsToRasterStreamAsync(memoryStream, screenshot);

        using (DataReader reader = new(memoryStream.GetInputStreamAt(0)))
        {
            await reader.LoadAsync((uint)memoryStream.Size);
            byte[] byteArray = new byte[memoryStream.Size];
            reader.ReadBytes(byteArray);

            return Convert.ToBase64String(byteArray);
        }                
    }     
}  

public static async Task<bool> CopyScreenshotToClipboardAsync(Screenshot screenshot)
{
    InMemoryRandomAccessStream stream = new();
    await RenderPixelsToRasterStreamAsync(stream, screenshot);

    DataPackage dataPackage = new();
    dataPackage.RequestedOperation = DataPackageOperation.Copy;
    dataPackage.SetBitmap(RandomAccessStreamReference.CreateFromStream(stream));

    try
    {
        Clipboard.SetContent(dataPackage);
        return true;
    }
    catch (Exception)
    {
        return false;
    }
    finally
    {
        Debug.WriteLine("Clipboard flushed");
        Clipboard.Flush();
        stream.Dispose();
    }
}

private static async Task RenderPixelsToRasterStreamAsync(IRandomAccessStream stream, Screenshot screenshot)
{
    double dpi = App.Window.DPI;
    Debug.WriteLine($"RenderPixelsToRasterStreamAsync method called with {(uint)screenshot.Width} {(uint)screenshot.Height} {dpi}");
    BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
    Debug.WriteLine("Encoder initialised");
    encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, (uint)screenshot.Width, (uint)screenshot.Height, dpi, dpi, screenshot.Pixels);
    Debug.WriteLine("Bitmap set");
    await encoder.FlushAsync();
    Debug.WriteLine("Encoder flushed");
}

我可以毫无问题地调用

ByteArrayToBase64PNGStringAsync
CopyScreenshotToClipboardAsync
的任何组合/重复,除非我调用
CopyScreenshotToClipboardAsync
然后
ByteArrayToBase64PNGStringAsync
,在这种情况下,代码无限期地挂在
await encoder.FlushAsync()
上。 (自始至终都使用 UI 线程)。

任何人都可以建议可能是什么原因造成的吗?

c# bitmap screenshot winui-3
1个回答
0
投票

在尝试制作一个可重现的示例时,我在调用代码中发现了一个

.GetAwaiter().GetResult()
,它似乎仅在我在问题中描述的场景中造成了死锁。用异步函数替换它解决了这个问题。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.