好的,首先我使用的是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
答案 0 :(得分:3)
如果您的answer_timer
是WinForm计时器控件(System.Windows.Forms.Timer
),那么您无法从UI线程以外的任何线程启动它。从另一个线程启动WinForm定时器控件不会导致异常,但它根本不起作用。
要正确启动计时器,您可以在UI线程上调用此方法,如下所示:
Me.Invoke(New MethodInvoker(AddressOf answer_timer.Start))
或者,您可以使用System.Timers.Timer
或System.Threading.Timer
。这些都可以从任何线程中正常工作。 System.Timers
中的那个是与控件最接近的等价物。但是,由于这两个计时器通过一个新线程进行勾选,因此在对UI进行任何操作之前,在计时器勾号上执行的代码仍然需要调用回UI线程。因此,如果您的计时器刻度代码对表单或控件执行任何操作,则可能更容易坚持使用WinForm计时器控件。
答案 1 :(得分:1)
猜测:您的计时器在Windows窗体上,并且您正在尝试使用另一个线程来更新它? 当你尝试这个时,事件不会被触发(如果我没记错的话,beheaviour看起来很奇怪)。您遇到此问题,因为您的第二个线程无法直接更新UI线程。您应该尝试在UI线程上使用委托,该委托由第二个线程调用。
您只需将Timer.start包装到委托中即可。 这里有一个问题:如果您的计时器应该在线程2上执行某些操作,您将再次遇到问题。因此,最好将Timer移至线程2(昏暗计时器作为NEW windows.forms.timer)并在那里运行。在它的tick事件中,它可以提出一个代表来更新倒计时......