如何在下面的代码中更新我的label1文字?我得到一个“调用线程无法访问此对象,因为不同的线程拥有它”错误。我已经读过其他人使用过Dispatcher.BeginInvoke,但我不知道如何在我的代码中实现它。
public partial class MainWindow : Window
{
System.Timers.Timer timer;
[DllImport("user32.dll")]
public static extern Boolean GetLastInputInfo(ref tagLASTINPUTINFO plii);
public struct tagLASTINPUTINFO
{
public uint cbSize;
public Int32 dwTime;
}
public MainWindow()
{
InitializeComponent();
StartTimer();
//webb1.Navigate("http://yahoo.com");
}
private void StartTimer()
{
timer = new System.Timers.Timer();
timer.Interval = 100;
timer.Elapsed += timer_Elapsed;
timer.Start();
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
tagLASTINPUTINFO LastInput = new tagLASTINPUTINFO();
Int32 IdleTime;
LastInput.cbSize = (uint)Marshal.SizeOf(LastInput);
LastInput.dwTime = 0;
if (GetLastInputInfo(ref LastInput))
{
IdleTime = System.Environment.TickCount - LastInput.dwTime;
string s = IdleTime.ToString();
label1.Content = s;
}
}
}
答案 0 :(得分:6)
您可以尝试这样的事情:
if (GetLastInputInfo(ref LastInput))
{
IdleTime = System.Environment.TickCount - LastInput.dwTime;
string s = IdleTime.ToString();
Dispatcher.BeginInvoke(new Action(() =>
{
label1.Content = s;
}));
}
答案 1 :(得分:2)
您需要从主线程中保存Dispatcher.CurrentDispatcher
:
public partial class MainWindow : Window
{
//...
public static Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
//...
}
然后,只要您需要在主线程的上下文中执行某些操作,就可以执行以下操作:
MainWindow.dispatcher.Invoke(() => {
label1.Content = s;
});
注意,与Dispatcher.BeginInvoke
不同,Dispatcher.Invoke
是异步的。 您可能希望在此处进行同步调用。对于这种情况,异步调用似乎没问题,但通常你可能想要更新主要的thead上的UI,然后继续在当前线程上知道更新已经完成。
这是一个similar question的完整示例。
答案 2 :(得分:1)
有两种方法可以解决这个问题:
首先,您可以使用DispatcherTimer
类而不是this MSDN article类,如{{3}}中所示,它会修改Dispatcher线程上Timer
事件中的UI元素。< / p>
其次,使用现有的Elapsed
类,您可以在timer_Elapsed事件中使用Timer
方法代码,如下所示:
Dispatcher.BegineInvoke()