2秒ごとにラベルを更新するCPUフレンドリーな無限ループを作成しようとしています。それはラベルを更新するために来るときDispatcherを使用してラベルの前景を変更すると例外がスローされる
、私はそのContent
とToolTip
値を変更する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フレンドリーではありません知っていますループ、私はテスト目的のためにこれを作った)。
よう
GetColorByPing()
戻っは何か、それは問題が何であるか確かに言うすることはできません。しかし、あなたが共有したコードの小さなビットに基づいて、私はあなたがバックグラウンドスレッドで 'Brush'オブジェクトを作成していると思います。これは一般的に許可されていません。 'Brush'を作成した後に' Freeze() 'を呼び出すことで、それを動作させることができます。しかし、正直なところ、MVVM /データバインディングとスタイルの使用を含め、WPFプログラムを書く正しい方法を学ぶ方が良いでしょう。その後、 'BeginInvoke()'はまったく必要ありません。 (そして、 'Thread.Sleep(1)'を使うことは_not_ _ "CPU-friendly" _です。) –コード全体でそれほど多くは追加されません。 'PerformPing'の唯一のことは、pingを実行し、' Brush'オブジェクトが 'BrushConverter'を介して検索された結果で' SetPing'を呼び出すことです。それは助けになりますか? Freeze()を試してみましょう。 さらに、これは自分のために作ったプログラムです。このスタイルではスタイルやデータバインディングは必要ありません。 さらに、私は '(はい、これはCPUに優しいループではないことを知っていますが、私はこれをテスト目的で作ったのですが)」と言っています。 どうもありがとうございました。 – Hawezo
_ "このスタイルではスタイルやデータバインディングは必要ありません" - 確かにそうです。それが_ "あなた自身のために作った非常に小さなプログラム"だからといって、_それはそれをすることに価値がないわけではありません。 –