这个问题在这里已有答案:
我正在使用uwp应用程序中的RenderTargetBitmap将UIelement转换为流。但我不知道如何使线程等到转换流。我尝试过使用这些建议,但我无法找到合适的解决方案。任何帮助深表感谢。
{
for (int count = 0; count <= Textpage.Children.Count; count++)
{
if (Textpage.Children[count] is Viewbox)
{
CustomView customView = (Textpage.Children[count] as Viewbox).Child as CustomView;
UIElement frameworkElement = customView as UIElement;
(Textpage.Children[count] as Viewbox).Child = null;
var element = (PdfDocumentPanel.Children[count] as Border).Child as Canvas;
Textpage.Children.Remove((Textpage.Children[count] as Viewbox));
SaveCustomAnnotation(frameworkElement, pageIndex, documentToBeSaved);
}
}
}
Stream savedStream = new MemoryStream();
}
internal async void SaveCustomAnnotation(UIElement element, int pageIndex, PdfLoadedDocument loadedDocument)
{
Type pageChild = null;
IRandomAccessStream randomStream;
randomStream = await Task.Run(() => ConvertToImage(element));
}
public async Task<IRandomAccessStream> ConvertToImage(UIElement element)
{
InMemoryRandomAccessStream randomAccessStream = null;
IBuffer pixelBuffer = null;
RenderTargetBitmap bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(element);
pixelBuffer = await bitmap.GetPixelsAsync();
var logicalDpi = DisplayInformation.GetForCurrentView().LogicalDpi;
using (randomAccessStream = new InMemoryRandomAccessStream())
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, randomAccessStream);
encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
(uint)bitmap.PixelWidth,
(uint)bitmap.PixelHeight,
logicalDpi,
logicalDpi,
pixelBuffer.ToArray());
await encoder.FlushAsync();
}
return randomAccessStream;
}
我希望在移动初始化新内存流之前完全完成SaveCustomannotation方法
问题在于这是对async void
的滥用,这使你无法等待它。当你开始时,一个好的规则是,如果你输入单词async void
stop ...从你的计算机退后一步,告诉你自己可能有更好的方法......它们应该主要用于事件处理程序。
基本上SaveCustomAnnotation
应该返回Task
internal async Task SaveCustomAnnotation(UIElement element, int pageIndex, PdfLoadedDocument loadedDocument)
然后你需要await
它
await SaveCustomAnnotation(frameworkElement, pageIndex, documentToBeSaved);
因此,它的调用方法也应该是async Task
(一直到调用链),只有它们应该是async void
并且只有它是一个事件处理程序。
最后一点
Async void
方法具有不同的错误处理语义。当从async Task
或async Task<T>
方法抛出异常时,该异常被捕获并放置在Task
上。使用async void
方法,没有Task对象(它们运行未被观察到),因此从async void
方法抛出的任何异常都将直接在启动时处于活动状态的SynchronizationContext引发。
总之,总是在这种方法中捕获和处理异常
正如Jonathon Chase所说(并且正确地如此)。
如果这就是它,你应该只是从main方法调用它并等待它,因为它仍然返回一个任务并标记为async
internal async void SaveCustomAnnotation(UIElement element, int pageIndex, PdfLoadedDocument loadedDocument)
{
Type pageChild = null;
IRandomAccessStream randomStream;
randomStream = await Task.Run(() => ConvertToImage(element));
}
您可以删除整个方法,只需替换即可
await SaveCustomAnnotation(frameworkElement, pageIndex, documentToBeSaved);
同
var readstream = await ConvertToImage(frameworkElement);
关于这段代码还有更多的问题,但我认为它们可能属于另一个问题