3

好的,所以首先我使用的是 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
4

2 回答 2

3

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

要正确启动计时器,您可以像这样调用 UI 线程上的方法:

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

或者,您可以使用System.Timers.TimerSystem.Threading.Timer。其中任何一个都可以从任何线程正常工作。inSystem.Timers是与控件最接近的等效项。但是,由于这两个计时器通过新线程计时,因此在计时器计时时执行的代码在对 UI 执行任何操作之前仍需要调用回 UI 线程。因此,如果您的计时器滴答代码正在对表单或控件执行任何操作,那么坚持使用 WinForm 计时器控件可能会更容易。

于 2013-01-07T14:56:23.223 回答
1

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

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

于 2013-01-07T14:18:56.687 回答