在线程运行时使用计时器

时间:2013-01-07 13:49:47

标签: vb.net multithreading timer

好的,首先我使用的是visual basic 2010,我有一个不断循环的线程来检查来自远程客户端的网络请求。我想要做的是当客户端提交某个请求时,将触发一个计时器来启动表单上的倒计时,但由于某种原因,我无法在线程运行时让计时器启动。我也尝试在启动计时器之前中止线程,但这也不起作用。任何帮助都会受到赞赏,因为自上周以来,我一直在撞墙。

Do While p1buzzedstatus = False Or p2buzzedstatus = False Or p3buzzedstatus = False
    'Download Communication File'
    Try
        Threading.Thread.Sleep(1)
        Dim Aclient As New Net.WebClient
        Aclient.Credentials = New Net.NetworkCredential(remote_buzzer_registration.FTPUserName, remote_buzzer_registration.FTPPassword)
        If Aclient.DownloadString(BuzzerCommandURL) = "" Then
            'Don't Do Anything'
        Else
            'Check For Buzz'
            keypressed = Aclient.DownloadString(BuzzerCommandURL)
            Aclient.UploadString(BuzzerCommandURL, "")
            buzzercode()
            answer_timer.Start()  ' <--- HERE
        End If
    Catch ex As Exception
    End Try
Loop

2 个答案:

答案 0 :(得分:3)

如果您的answer_timer是WinForm计时器控件(System.Windows.Forms.Timer),那么您无法从UI线程以外的任何线程启动它。从另一个线程启动WinForm定时器控件不会导致异常,但它根本不起作用。

要正确启动计时器,您可以在UI线程上调用此方法,如下所示:

Me.Invoke(New MethodInvoker(AddressOf answer_timer.Start))

或者,您可以使用System.Timers.TimerSystem.Threading.Timer。这些都可以从任何线程中正常工作。 System.Timers中的那个是与控件最接近的等价物。但是,由于这两个计时器通过一个新线程进行勾选,因此在对UI进行任何操作之前,在计时器勾号上执行的代码仍然需要调用回UI线程。因此,如果您的计时器刻度代码对表单或控件执行任何操作,则可能更容易坚持使用WinForm计时器控件。

答案 1 :(得分:1)

猜测:您的计时器在Windows窗体上,并且您正在尝试使用另一个线程来更新它? 当你尝试这个时,事件不会被触发(如果我没记错的话,beheaviour看起来很奇怪)。您遇到此问题,因为您的第二个线程无法直接更新UI线程。您应该尝试在UI线程上使用委托,该委托由第二个线程调用。

您只需将Timer.start包装到委托中即可。 这里有一个问题:如果您的计时器应该在线程2上执行某些操作,您将再次遇到问题。因此,最好将Timer移至线程2(昏暗计时器作为NEW windows.forms.timer)并在那里运行。在它的tick事件中,它可以提出一个代表来更新倒计时......