使用Dispatcher更改标签的前景会引发异常

时间:2017-08-20 13:56:28

标签: c# multithreading dependency-properties dispatcher

我正在尝试建立一个CPU友好的无限循环,它将每2秒更新一次标签。

在更新标签时,我可以使用Dispatcher更改其ContentToolTip值,但我无法更改其Foreground某种原因。

  

出现InvalidOperationException :   不能使用属于另一个线程的DependencyObject而不是其Freezable父级。

有我的代码:

private void SetPing(Brush foreground, string content, string tooltip)
{
    try
    {
        this.Dispatcher.BeginInvoke(DispatcherPriority.Send, (Action)(() =>
        {
            this.Ping.Content = content;
            this.Ping.ToolTip = tooltip;
        }));

        // this.Dispatcher or this.Ping.Dispatcher throws the same error
        this.Ping.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
        {
            this.Ping.Foreground = foreground;
        }));
    }
    catch (Exception)
    {
    }
}

我在这里用PerformPing方法调用此代码:

new Thread(() =>
{
    while (true)
    {
        this.PerformPing(this.Host);
        Thread.Sleep(1);
    }
}).Start();

(是的,我知道这不是一个对CPU友好的循环,我是出于测试目的而做的)。

1 个答案:

答案 0 :(得分:0)

感谢Peter Duniho的回答,我发现刷子对象是在后台线程中创建的,这就是导致问题的原因。在Dispatcher调用中创建画笔可以解决问题。

private void SetPing(long ping, string content, string tooltip)
{
    try
    {
        this.Dispatcher.BeginInvoke(DispatcherPriority.Send, (Action)(() =>
        {
            this.Ping.Content = content;
            this.Ping.ToolTip = tooltip;
            this.SetDock();
        }));

        if (this.EnableColors)
        {
            this.Ping.Dispatcher.BeginInvoke(DispatcherPriority.Send, (Action)(() =>
            {
                this.Ping.Foreground = this.GetColorByPing(ping);
            }));
        }
    }
    catch (Exception ex)
    {
    }
}

GetColorByPing()返回return (SolidColorBrush)new BrushConverter().ConvertFromString("#b71c1c");

之类的内容