如何在多线程应用程序中使用Timer

时间:2015-10-19 19:01:15

标签: c# winforms

我使用C#设计了一个Windows应用程序。应用程序的表单由几个标签和一个按钮组成。当应用程序启动时,我实例化一个UdpListener并且我用它启动一个单独的线程,以便在侦听器等待传入的数据包时实现响应。当数据到达时,监听线程需要更新表单的控件,为此我已经声明了委托函数,并在通过这些函数看到它们之前检查每个控件是否需要调用。

该应用程序工作正常至今。我现在想要实现定时器功能,这样如果检测到接收数据的暂停时间超过2秒,我想将标签变为红色。我正在尝试使用System.Timers.Timer类,并按照Microsoft的示例(https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx),实现如下:

private static void SetTimer()
   {
        // Create a timer with a two second interval.
        aTimer = new System.Timers.Timer(2000);
        // Hook up the Elapsed event for the timer. 
        aTimer.Elapsed += OnTimedEvent;
        aTimer.AutoReset = true;
        aTimer.Enabled = true;
    }

    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        Console.WriteLine("The Elapsed event was raised at {0:HH:mm:ss.fff}",
                          e.SignalTime);
    }  

我从我的主窗体调用SetTimer()。虽然上面编译,当我尝试用我的控件替换Console ....,比如说lblStatus,编译器抱怨我试图从静态上下文引用非静态控件。尝试构建与标签和文本框相似的功能,并使用Invoke方法检查也不起作用。如果有人实现了这样的功能,我会非常感兴趣你的意见。

关于此处可能存在的重复问题,请注意我假设方法和事件 是静态的(因为此代码是从上面引用的示例中复制的)因此编译错误;我知道错误意味着什么,我只是对于如何在给定事件的静态性质的情况下从另一个线程引用表单控件感到困惑。我也很好奇这个静态事件是怎么来的,Console仍然可以访问;我想它不被认为是一种控制。我希望这对论坛有意义。

1 个答案:

答案 0 :(得分:0)

如果没有静态函数的实例引用,则无法访问成员变量。这是因为静态函数不是实例的一部分,并且无法访问this

您应该将SetTimerOnTimedEvent声明为普通实例方法,并声明计时器相同(非静态)。这样,所有函数都将成为实例的一部分,并且可以访问其他实例变量(控件)。

根据您的问题,您似乎不需要其中任何一个是静态的。