Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中等待异步任务完成?_C#_Async Await - Fatal编程技术网

如何在C#中等待异步任务完成?

如何在C#中等待异步任务完成?,c#,async-await,C#,Async Await,我正在使用uwp应用程序中的RenderTargetBitmap将UIelement转换为流。但是我不知道如何让线程等待流的转换。我曾尝试采用这些建议,但未能找到合适的解决办法。非常感谢您的帮助 { for (int count = 0; count <= Textpage.Children.Count; count++) { if (Textpage.Children[count] is Viewbox) {

我正在使用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;
}
{
对于(int count=0;count ConvertToImage(元素));
}
公共异步任务转换图像(UIElement)
{
InMemoryRandomAccessStream randomAccessStream=null;
IBuffer pixelBuffer=null;
RenderTargetBitmap位图=新建RenderTargetBitmap();
等待位图.RenderAsync(元素);
pixelBuffer=等待位图。GetPixelsAsync();
var logicalDpi=DisplayInformation.GetForCurrentView().logicalDpi;
使用(randomAccessStream=new InMemoryRandomAccessStream())
{
var encoder=等待BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId,randomAccessStream);
编码器.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode。忽略,
(uint)bitmap.PixelWidth,
(uint)bitmap.PixelHeight,
logicalDpi,
logicalDpi,
pixelBuffer.ToArray());
等待编码器。FlushAsync();
}
返回随机数据流;
}

我希望在移动初始化新内存流之前完全完成SaveCustomannotation方法

这里的问题是误用了
异步void
,这使您无法等待它。开始时的一个好规则是,如果键入单词
async void
stop。。。从你的电脑前退一步,告诉你自己可能有更好的方法。。。它们应该主要用于事件处理程序

基本上,
SaveCustomAnnotation
应该返回一个
Task

internal async Task SaveCustomAnnotation(UIElement element, int pageIndex, PdfLoadedDocument loadedDocument)
然后你需要等待它

await SaveCustomAnnotation(frameworkElement, pageIndex, documentToBeSaved);
因此,它的调用方法也应该是
async Task
(一直到调用链的上游),只有这样,它们的调用方法才应该是
async void
,并且只有当它是一个事件处理程序时

最后一个音符

Async void
方法具有不同的错误处理语义。当从
异步任务
异步任务
方法中抛出异常时,将捕获该异常并将其放置在
任务
中。使用
async void
方法时,没有任务对象(它们在未观察到的情况下运行),因此从
async void
方法抛出的任何异常将直接在启动时处于活动状态的SynchronizationContext上引发

简而言之,在这些方法中始终捕获并处理来自的异常


正如所逃避的那样(这是正确的)

如果这就是它所做的一切,您可能应该从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);

关于这段代码还有很多不确定的地方,但我认为它们可能属于另一个相关问题:

。Async void与Async void大不相同,不仅因为它不能等待,而且因为Async void方法中任何未经处理的异常都可能导致程序崩溃。另请参阅,其中包含有关C#
Async
/
await
功能的详细信息。你几乎不是第一个就不能等待
async void
方法提出问题的人。@Jonathon:“我们将看到的有很多不同的变体”--将其归入同一类
NullReferenceException
。我可能有点简短,但事实是,人们在没有做任何真正的研究的情况下发布了这类问题。每一篇讨论C#
异步
/
等待
功能的合理参考文献,包括微软自己的文档、大量关于堆栈溢出的文章(包括我提供链接的事实上的规范性文章),以及各种专家的博客文章,都解释了
异步无效
的危害。这是最基本的。
var readstream = await ConvertToImage(frameworkElement);