我正在尝试每秒刷新标签内容。所以我定义了两种方法如下。我在startStatusBarTimer()
的构造函数中使用Window
。
代码:
private void startStatusBarTimer()
{
System.Timers.Timer statusTime = new System.Timers.Timer();
statusTime.Interval = 1000;
statusTime.Elapsed += new System.Timers.ElapsedEventHandler(statusTimeElapsed);
statusTime.Enabled = true;
}
private void statusTimeElapsed(object sender, ElapsedEventArgs e)
{
lblNow.Content = DateTime.Now.ToString("yyyy/MM/dd");
}
但是我收到了这个错误:
调用线程无法访问此对象,因为另一个线程拥有它。
有什么问题?或者我该怎么办?
答案 0 :(得分:12)
您正面临thread affinity问题。由于在background thread
上调用了已发生的事件,因此无法从后台线程访问UI控件。您需要将操作放在UI dispatcher
上,以便将其分派到UI线程 -
private void statusTimeElapsed(object sender, ElapsedEventArgs e)
{
App.Current.Dispatcher.Invoke((Action)delegate
{
lblNow.Content = DateTime.Now.ToString("yyyy/MM/dd");
});
}
或强>
您可以使用专为此目的而构建的DispatcherTimer
。您可以从其Tick
事件处理程序访问UI控件。请参阅此处的示例MSDN。
答案 1 :(得分:2)
只需使用以下代码刷新WPF应用程序中的任何控件。您必须在同一名称空间中通过此类。
public static class ExtensionMethods
{
private static Action EmptyDelegate = delegate() { };
public static void Refresh(this UIElement uiElement)
{
uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
}
}
之后使用如下。
lable1.Refresh();