vb.net 在线程运行时使用计时器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14197324/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 11:48:46  来源:igfitidea点击:

Using a timer when a thread is running

vb.netmultithreadingtimer

提问by slister

Ok so first off I am using visual basic 2010 and I have a thread that continuously loops to check for network requests from the remote clients. What I would like to do is when a client submits a certain request a timer will be triggered to start a countdown on the form, but for some reason I can't get the timer to start at all while the thread is running. I have also tried to abort the thread before starting the timer and that doesn't work either. Any help would be appreciated because I have been banging my head against the wall about this since last week.

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

回答by Steven Doggart

If your answer_timeris a WinForm timer control (System.Windows.Forms.Timer), then you cannot start it from any thread other than the UI thread. Starting a WinForm timer control from another thread will not cause an exception, but it will not work at all either.

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

To start the timer properly, you can invoke the method on the UI thread like this:

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

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

Alternatively, you could use either the System.Timers.Timeror the System.Threading.Timer. Either of those work fine from any thread. The one in System.Timersis the closest equivalent to the control. However, since these other two timers tick via a new thread, the code that executes upon the timer tick will still need to invoke back to the UI thread before doing anything to the UI. So, if your timer tick code is doing anything to the form or controls, it's probably easier to just stick with the WinForm timer control.

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

回答by Christian Sauer

At a guess: Your Timer is on a Windows Form and you are trying to use another Thread to update it? When you try this, the event will not be triggered (the beheaviour is looking weird if I recall correctly). You are running into this issue because the UI thread cannot be updated by your second thread directly. You should try to use a delegate on your UI thread, which is called by your second thread.

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

You would simply wrap the Timer.start into a delegate. Here is the catch: You will into problems again, if your timer shall do something on thread 2. So maybe it would be best to move the Timer to Thread 2 (dim timer as NEW windows.forms.timer) and run it there. In it's tick event it could raise a delegate to update the countdown...

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