【问题标题】:How to fix a cross-thread exception in C#? [duplicate]如何修复 C# 中的跨线程异常? [复制]
【发布时间】:2014-06-06 15:53:02
【问题描述】:

我正在尝试在 UI 控件上使用 System.Timers.Timer。

错误: System.Timers.Timer“跨线程操作无效:控制'txtOutput'从创建它的线程以外的线程访问。”

我的代码如下:

System.Timers.Timer timeRandomEvent = new System.Timers.Timer(10 * 1000); 

// timer for random events  
timeRandomEvent.Elapsed += new ElapsedEventHandler(timeRandomEvent_Elapsed);
timeRandomEvent.Start();

void timeRandomEvent_Elapsed(object sender, ElapsedEventArgs e) 
{
    wl("Adding some text to a text box.");   // Exception occurs here
}

有没有办法允许它,或者另一种可能很容易的替代方法?

【问题讨论】:

  • 你能用System.Windows.Forms.Timer代替吗?
  • @hatchet 虽然这似乎是 WinForms 的自然选择,但 System.Windows.Forms.Timer 实际上不如 System.Timers.Timer (limited to accuracy of 55 milliseconds) 准确。所以如果 OP 想要一个带有更精确计时器的 WinForms 应用程序,那么System.Timers.Timer 就是要走的路。
  • @JWLim - 我想过这个问题,但是他/她的代码中的计时器设置为每 10 秒触发一次,我认为 55 毫秒的分辨率问题可能无关紧要。
  • @hatchet 我同意,但仍然值得一提,因为我们不确定这是否是 OP 将使用的实际代码 :) 此外,我认为了解您的选项,以免您尝试将它们用于非设计用途。

标签: c# winforms timer


【解决方案1】:

您需要将计时器的SynchronizingObject 属性设置为表单对象。

timer.SynchronizingObject = this; // Synchronize the timer with this form UI

官方文档相关摘录:

当 Elapsed 事件由可视 Windows 窗体组件处理时, 比如一个按钮,通过系统线程访问组件 pool 可能会导致异常或可能无法正常工作。避免这种情况 通过将 SynchronizingObject 设置为 Windows 窗体组件来产生效果, 这会导致调用处理 Elapsed 事件的方法 创建组件的同一线程。

【讨论】:

  • 太棒了。谢谢!
  • @Phil 不客气,我很高兴它有帮助。我认为你应该用[winforms] btw(也许[timer])来标记你的问题,而不是[multithreading]
猜你喜欢
  • 1970-01-01
  • 2011-02-28
  • 2017-09-24
  • 1970-01-01
  • 1970-01-01
  • 2016-01-05
  • 2021-02-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多