繁体   English   中英

使用定时器和 2 个按钮的跨线程操作无效

[英]Cross-thread operation not valid using timer and 2 buttons

我遇到了这个问题...

对此有什么好的解决方案?

 private void button1_Click(object sender, EventArgs e)
    {
        aTimer.Enabled = true;
        button1.Enabled = false;

    }

    private void button2_Click(object sender, EventArgs e)
    {
        aTimer.Enabled = false;
    }

    private void timer_is_working(object source, ElapsedEventArgs e)
    {
        aTimer.Enabled = false;
        button1.Enabled = true;
    }

谢谢! 亲切的问候丹尼尔·鲁舍尔

所以你没有说清楚,但基于ElapsedEventArgs类型, timer_is_working似乎是System.Timers.Timer实例的Elapsed事件。

请注意,.NET Framework 类库包括四个名为 Timer 的类,每个类提供不同的功能:

  • System.Timers.Timer:定期触发事件。 该类旨在用作多线程环境中的基于服务器或服务的组件。
  • System.Threading.Timer:定期在线程池线程上执行单个回调方法。 回调方法是在定时器实例化时定义的,不能更改。 与 System.Timers.Timer 类一样,此类旨在用作多线程环境中的基于服务器或服务组件。
  • System.Windows.Forms.Timer:一个 Windows 窗体组件,它定期触发一个事件。 该组件专为在单线程环境中使用而设计。
  • System.Web.UI.Timer:一个 ASP.NET 组件,它定期执行异步或同步网页回发。

如果这是 Windows.Forms 应用程序,请改用System.Windows.Forms.Timer (您可以在工具箱/组件中找到它)。 它的Tick事件在 UI 线程中引发,因此可以从那里访问您的控件。

如果您有使用System.Timers.Timer的特殊原因(例如精度),您必须将您的访问权限包装到一个Invoke调用中:

Invoke(new Action(() => { button1.Enabled = true; }));

您可以使用Invoke通过使用 UI 线程来更新 UI。

试试这个例子

private void timer_is_working(object source, ElapsedEventArgs e)
{
    ExecuteSecure(() => aTimer.Enabled = false);        
    ExecuteSecure(() => button1.Enabled = true);
}

private void ExecuteSecure(Action action)
{
    if (InvokeRequired)
    {
        Invoke(new MethodInvoker(() =>
        {
            action();
        }));
    }
    else
    {
        action();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM