微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从 C# 类库中的颜色在 UWP 中创建 SolidColorBrush?

如何解决如何从 C# 类库中的颜色在 UWP 中创建 SolidColorBrush?

我有一个 UWP 应用,它有 XAML 页面和类库来帮助聚合某些功能

我有某些对象(动态)具有名为 Brush属性。此属性包含可在 XAML 中绑定的任何 Brush,以指示用于使用此画笔在控件内绘制控件/项的画笔。这一切都封装在各种转换器中,以便在绑定期间使用。

我遇到了几个问题:

  1. 从非 UI 调度程序运行转换器会引发“Marshalled For Another Thread”错误

  2. dispatcher.RunAsync 方法中包装新的 SolidColorBrush(color) 会导致死锁。

我创建了一个新的异步函数,以便在同步方法中更方便地运行它。

这是转换器(称为 RandomBrush)的代码

return Task.Run(async () => await Data.CreateSolidColorBrush(color)).Result;

这是 Data.CreateSolidColorBrush 函数代码

public async static Task<Brush> CreateSolidColorBrush(Color color)
        {
            Brush brush = null;
            var dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.dispatcher;
            //var dispatcher = Window.Current.dispatcher;
            await dispatcher.RunAsync(CoredispatcherPriority.normal,() => 
            {
                try { brush = new SolidColorBrush(color); } 
                catch (Exception ex) 
                { }
            });
            return brush;
        }

我尝试了各种异步/任务/动作/等方法,但有些根本不运行动作,有些会导致死锁。

从一种颜色创建画笔的最佳方法是什么,没有所有的复杂性!

解决方法

首先:

return Task.Run(async () => await Data.CreateSolidColorBrush(color)).Result;

可以简化为:

return Data.CreateSolidColorBrush(color).Result;

关于死锁:

Dispatcher.RunAsync 将 lambda 放在调度程序中的待处理工作列表中,并返回一个 Task,在工作完成时将完成。

您等待任务,因此您将等待其完成。但是您可能在调度程序的线程上,它等待您继续执行挂起的工作。这是一个死锁。

在调用 RunAsync 之前,您应该检查您是否不在 UI 线程上,如果您在 UI 线程上,则立即执行。

最后,我什至不确定您是否需要在 UI 线程上构建画笔。所以测试一下你什么时候会有一个工作代码。

关于Marshalled For Another Thread

您没有显示任何代码。如果以上内容不能解决问题,请使用调度程序通过 RunAsync 设置视图属性。同样,您将不得不测试您是否在 UI 线程上。

如果您在 UI 线程上或通过调度程序,请参阅 https://stackoverflow.com/a/63376211/361177 以获取帮助程序进行测试并立即执行操作。

,

我能够使用以下代码修复它:

公共异步静态任务 CreateSolidColorBrush(Color color)

{
    Brush brush = null;
    Threading.ThreadSafe(() => brush = new SolidColorBrush(color));
    if (brush == null)
    {
        Threading.ThreadSafe(() =>
        {
            try { brush = new SolidColorBrush(color); }
            catch (Exception Ex)
            { }
        }
        );
    }
    return brush;
}

public static class Threading
    {

        private static CoreDispatcher Dispatcher =>
        Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher;

        public static async void ThreadSafe(DispatchedHandler action)
        {
            // Calls Dispatcher.RunAsync to run a method on the Main UI Thread
            IAsyncAction UiThread(DispatchedHandler proc) => Dispatcher.RunAsync(CoreDispatcherPriority.Normal,proc);

            // Checks to see if this was called from the Main UI thread 
            // If we are in the Main UI thread then Invoke the action 
            // Otherwise: Send it to run in the Main Ui Thread.

            if (Dispatcher.HasThreadAccess) 
            {
                action.Invoke(); 
            } 
            else 
            {
                await UiThread(action); 
            }
        }
    }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。