使用Timer的交叉线程错误处理表单

时间:2011-12-16 16:56:40

标签: c# winforms exception error-handling

我在我的一个窗体上设置了一个10秒的计时器。对于OnTimedEvent,我设置表格在时间结束后处理。但是似乎有错误

  

用户代码未处理InvalidOperationException。

     

跨线程操作无效:控制'notificationForm'从其创建的线程以外的线程访问。

错误在线

protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

我的计时器事件的代码是

    private void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        this.Dispose();
    }

任何人都知道如何解决这个问题?谢谢!

4 个答案:

答案 0 :(得分:4)

看起来您正在使用System.Timers.Timer

请尝试使用System.Windows.Forms.Timer并订阅Tick事件。

如果您必须使用该计时器,可以尝试将代码更改为:

private void OnTimedEvent(object source, ElapsedEventArgs e)
{
   this.BeginInvoke((MethodInvoker)delegate { this.Dispose(); });
}

答案 1 :(得分:1)

或者只是:

this.Invoke((Action)(() => { this.Dispose(); }));

您可以在一行中执行此操作:

timer1.Tick += (_, __) => { this.Invoke((Action)(() => { this.Dispose(); })); };

答案 2 :(得分:1)

正如其他人所说,问题是你的计时器正在运行一个线程并试图处理在另一个线程上创建的对象。在尝试访问表单之前,您需要在表单上调用dispose方法。

要注意的基本事项是,如果您尝试从另一个线程更改设计器中创建的表示对象,则需要检查是否需要调用。

void OnTick()
{
    if (InvokeRequired)
        Invoke(new MethodInvoker(OnTick));
    else
    {
        Dispose();
    }
}

答案 3 :(得分:1)

private void OnTimedEvent(object source, ElapsedEventArgs e)
{
    this.Invoke(new Action(() => this.Dispose()));
}

这可以正常使用