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

本文关键字:线程 操作 无效 按钮 计时器 2个 | 更新日期: 2023-09-27 18:10:47

我遇到了这个问题…

这个问题有什么好的解决方案?

 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;
    }

谢谢!亲切的问候丹尼尔Ruescher

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

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

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

  • System.Timers。定时器:每隔一段时间触发一个事件。该类旨在用作基于服务器的或服务
  • System.Threading。定时器:每隔一段时间对线程池线程执行一个回调方法。回调方法是在计时器实例化时定义,不能更改。就像在System.Timers.Timer类中,这个类的目的是用作基于服务器或服务的组件。
  • System.Windows.Forms。定时器:一个Windows窗体组件,定期触发一个事件。该组件设计用于单线程环境。
  • System.Web.UI。定时器:一个ASP。. NET组件,以一定的间隔执行异步或同步的网页回发。

如果这是一个Windows。表单应用程序,使用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();
    }
}