我的计时器事件崩溃,因为事件被称为在不同的线程(My Timer event crashes bec

2019-08-03 01:32发布

我得到的错误“跨线程操作无效:控制‘label1的’从比它创建的线程以外的线程访问。” 当我运行这段代码:

using System;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Timers;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        System.Timers.Timer T = new System.Timers.Timer();
        public Form1()
        {
            InitializeComponent();
            T.Elapsed += new ElapsedEventHandler(T_Elapsed);
            T.Start();
        }

        void T_Elapsed(object sender, ElapsedEventArgs e)
        {
            label1.Text = "This will not work";
        }
    }
}

我以为事件在同一个线程跑了,因为他们在被触发。

Answer 1:

您使用的可能是一种错误的定时器。 尝试的WinForms计时器,它的GUI线程上运行,这样你就不必做调用



Answer 2:

我们在NET(Timers.Timer,Threading.Timer和Windows.Forms.Timer)3个定时器类,但只有一个Windows.Forms的有一个Tick事件。

当正常使用(即拖动到设计时的形式或某种形式的代码创建)的事件是主线程上运行,而不会出现你的问题。

因此,它是最有可能创建在另一个线程Timer对象,你应该编辑您的问题向我们展示了如何/在哪里创建它,并告诉我们,如果它是故意的另一个线程。



Answer 3:

虽然“接受”的答案是技术上正确(这将解决这个问题)这不回答这个问题。

答案是使用

void T_Elapsed(object sender, ElapsedEventArgs e)
{
    this.BeginInvoke(new MethodInvoker(delegate(){
        label1.Text = "This will work";
    }));
}

http://jaysonknight.com/blog/archive/2007/02/14/using-anonymous-methods-for-control-invoke-control-begininvoke.aspx



Answer 4:

你是否记得使用InvokeRequired ? 它可以让你更新从计时器线程UI线程上的UI元素。



Answer 5:

我假设你是在谈论一个WinForms应用程序。

当试图从另一个线程更新表单元素(它生活在UI线程上),则需要使用Control.Invoke或Control.BeginInvoke 。 你传递一个委托要调用(或传递一个匿名方法),然后该委托被调用UI线程,而不是调用线程的方法。



Answer 6:

是的,事件在由此引发他们在同一个线程执行。 它只是恰巧, System.Timers.Timer使用ThreadPool默认为提高线程时Elapsed事件。 使用SynchronizingObject属性使Elapsed事件处理程序的托管目标对象,而不是线程上执行。

public partial class Form1 : Form
{
  System.Timers.Timer T = new System.Timers.Timer();

  public Form1()
  {
    InitializeComponent();
    T.Elapsed += new ElapsedEventHandler(T_Elapsed);
    T.SynchronizingObject = this;
    T.Start();
  }

  void T_Elapsed(object sender, ElapsedEventArgs e)
  {
    label1.Text = "This will not work";
  }
}


Answer 7:

如果你这样做异步(这听起来像你是),请确保你赶上在事件处理程序或回调例外。 如果后台线程抛出一个异常,它会崩溃的应用程序。 这是最常见的原因是我见过的这种行为。



Answer 8:

我不是一个WinForm开发。 但我听说您正在使用的东西regararding Timer类。 我想你可能要设置这些属性和检查。

T.Interval = 5000; //in Mili Seconds
T.Enabled = true;


文章来源: My Timer event crashes because the events are called on a different thread