我的 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 线程)。
任何人都可以建议可能是什么原因造成的吗?
在尝试制作一个可重现的示例时,我在调用代码中发现了一个
.GetAwaiter().GetResult()
,它似乎仅在我在问题中描述的场景中造成了死锁。用异步函数替换它解决了这个问题。