如何在 UWP 后台任务中使用 XAML UI 元素?

Posted

技术标签:

【中文标题】如何在 UWP 后台任务中使用 XAML UI 元素?【英文标题】:How to use XAML UI element in UWP Background task? 【发布时间】:2017-08-13 03:45:15 【问题描述】:

问题:我正在尝试使用其他一些 UI 元素(主要是文本块)创建一个网格,然后使用 RenderTargetBitmap 渲染网格并最后将其保存到图像文件中,在 后台任务

这是方法的代码:

  private async Task<bool> RenderGridAsync()
  
            Grid mainGrid = new Grid();
            TextBlock tText = new TextBlock()
            
                HorizontalAlignment = HorizontalAlignment.Left,
                TextWrapping = TextWrapping.Wrap,
                Text = "Some Example Text",
                VerticalAlignment = VerticalAlignment.Top,
                FontSize = 72,
                FontWeight = FontWeights.SemiLight
            ;
            mainGrid.Children.add(tText);
            RenderTargetBitmap rtb = new RenderTargetBitmap();
                await rtb.RenderAsync(mainGrid);

                var pixelBuffer = await rtb.GetPixelsAsync();
                var pixels = pixelBuffer.ToArray();
                var displayInformation = DisplayInformation.GetForCurrentView();
                var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("CurrentImage" + ".png", CreationCollisionOption.ReplaceExisting);
                using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                
                    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
                    encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                                         BitmapAlphaMode.Premultiplied,
                                         (uint)rtb.PixelWidth,
                                         (uint)rtb.PixelHeight,
                                         displayInformation.RawDpiX,
                                         displayInformation.RawDpiY,
                                         pixels);
                    await encoder.FlushAsync();
                

但是当我从后台任务的 Run() 方法调用此方法时,我收到以下错误:

我用谷歌搜索了一下异常,发现为了从非 UI 线程更新 UI 元素,我需要使用这个:

 await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher
                .RunAsync(CoreDispatcherPriority.Normal, async () => 
                await RenderGridAsync();
            );

但即使这样也给了我一个例外:

Exception thrown: 'System.Runtime.InteropServices.COMException' in BackgroundTask.winmd
WinRT information: Could not create a new view because the main window has not yet been created

据我所知,在添加 UI 元素之前需要一个视图,但我必须渲染网格并将其保存到后台任务中的图像中。 以前,我在 Windows Phone 8.1 中实现了这一点,没有任何问题..

是否不能在后台任务或非 UI 任务上使用 UI 元素? 如果是,我该怎么做?

【问题讨论】:

【参考方案1】:

我相信你忘了实现XamlRenderingBackgroundTask

提供在后台任务中从 XAML 树创建位图的能力。

【讨论】:

这正是我所需要的......!实现 XamlRenderingBackgroundTask 并覆盖 OnRun(IBackgroundTaskInstance taskInstance) 方法解决了我的问题..!

以上是关于如何在 UWP 后台任务中使用 XAML UI 元素?的主要内容,如果未能解决你的问题,请参考以下文章

在 UWP 中本地化 XAML UI 中的字符串

UWP DependencyObject 绑定 Windows.UI.Xaml.Markup.XamlParseException

UWP App 在发布模式下崩溃(故障模块:Windows.UI.Xaml.dll)

UWP Xaml文本块数据绑定 - 即使属性已更新,UI也不会更新

Windows 10 UWP 应用程序在启动时崩溃(错误模块名称:Windows.UI.Xaml.dll)

Xamarin.UWP应用程序无法启动,因为无法加载“Microsoft.Graphics.Canvas.UI.Xaml.CanvasImageSource”