2017-08-20 10 views
0

2秒ごとにラベルを更新するCPUフレンドリーな無限ループを作成しようとしています。それはラベルを更新するために来るときDispatcherを使用してラベルの前景を変更すると例外がスローされる

、私はそのContentToolTip値を変更するDispatcherを使用することができますが、私はいくつかの理由でそのForegroundを変更することはできません。

InvalidOperationExceptionが: はそのFreezableの親よりも別のスレッドに属しているのDependencyObjectを使用することはできません。

私のコードがあります:

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フレンドリーではありません知っていますループ、私はテスト目的のためにこれを作った)。

+0

ようGetColorByPing()戻っは何か、それは問題が何であるか確かに言うすることはできません。しかし、あなたが共有したコードの小さなビットに基づいて、私はあなたがバックグラウンドスレッドで 'Brush'オブジェクトを作成していると思います。これは一般的に許可されていません。 'Brush'を作成した後に' Freeze() 'を呼び出すことで、それを動作させることができます。しかし、正直なところ、MVVM /データバインディングとスタイルの使用を含め、WPFプログラムを書く正しい方法を学ぶ方が良いでしょう。その後、 'BeginInvoke()'はまったく必要ありません。 (そして、 'Thread.Sleep(1)'を使うことは_not_ _ "CPU-friendly" _です。) –

+0

コード全体でそれほど多くは追加されません。 'PerformPing'の唯一のことは、pingを実行し、' Brush'オブジェクトが 'BrushConverter'を介して検索された結果で' SetPing'を呼び出すことです。それは助けになりますか? Freeze()を試してみましょう。 さらに、これは自分のために作ったプログラムです。このスタイルではスタイルやデータバインディングは必要ありません。 さらに、私は '(はい、これはCPUに優しいループではないことを知っていますが、私はこれをテスト目的で作ったのですが)」と言っています。 どうもありがとうございました。 – Hawezo

+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) 
    { 
    } 
} 

どこ確実に問題を再現している[MCVE]良いなしreturn (SolidColorBrush)new BrushConverter().ConvertFromString("#b71c1c");

関連する問題