vb.net 从另一个线程激活计时器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18114611/
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
Activating timer from another thread
提问by Janno
So the purpose of it is to check the connection of the ftp server and if the ftp is up then enable timer1. I've read that threads don't work as synchonized and that is causing the problem. Without the thread it works fine, but the program hangs and stops responding constantly.
所以它的目的是检查 ftp 服务器的连接,如果 ftp 已启动,则启用 timer1。我读过线程不能同步工作,这导致了问题。没有线程它工作正常,但程序挂起并不断停止响应。
How can i activate a timer from another thread? Maybe invoking and delegating would work? But i don't know how to do that.
如何从另一个线程激活计时器?也许调用和委托会起作用?但我不知道该怎么做。
Public Function CanPortOpen(ByVal HostName As String, ByVal Port As Integer) As Boolean
Dim TCP As New System.Net.Sockets.TcpClient
Try
TCP.Connect(HostName, Port)
Catch
End Try
If TCP.Connected = True Then
CanPortOpen = True
TCP.Close()
Timer1.Enabled = True
Else
CanPortOpen = False
TCP.Close()
Timer1.Enabled = False
FTPup.Abort()
End If
End Function
Public Sub CheckConnection()
CanPortOpen("HostName", Port)
End Sub
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
TestFTP = New System.Threading.Thread(AddressOf CheckConnection)
TestFTP.IsBackground = True
TestFTP.Priority = Threading.ThreadPriority.AboveNormal
TestFTP.Start()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
FTPup = New System.Threading.Thread(AddressOf UploadToFTP)
FTPup.IsBackground = True
FTPup.Priority = Threading.ThreadPriority.AboveNormal
FTPup.Start()
End Sub
采纳答案by J...
I think before you start getting in too deep with threads you should start by looking at the BackgroundWorkercomponent. You can find it on your toolbar in the designer and can drop it on your form. It gives you several events
我认为在开始深入了解线程之前,您应该先查看BackgroundWorker组件。您可以在设计器的工具栏上找到它,也可以将其拖放到表单上。它给你几个事件
DoWork- hook up this event with whatever you want done in a background thread
DoWork- 将此事件与您想在后台线程中完成的任何事情挂钩
RunWorkerCompleted- hook up this event to run code in the main (UI) thread, triggered when the thread completes. Code here can interact with UI objects as normal.
RunWorkerCompleted- 连接此事件以在主 (UI) 线程中运行代码,当线程完成时触发。这里的代码可以像往常一样与 UI 对象交互。
There are other events that allow you to report progress to your main thread, etc. The purpose of the BackgroundWorker component is to make simple multithreading tasks like this easier.
还有其他事件允许您向主线程等报告进度。BackgroundWorker 组件的目的是使这样的简单多线程任务更容易。
Documentation is -> here
文档是 ->这里
See -> herefor examples of how to pass data from the worker thread to the main thread using EventArgs.
有关如何使用 EventArgs 将数据从工作线程传递到主线程的示例,请参见 ->此处。
Alternatively, if you just want to run the timer from your thread you can do it like this :
或者,如果您只想从您的线程运行计时器,您可以这样做:
'Declare an appropriate delegate
Delegate Sub dlgTimerEnable(ByVal enable as Boolean)
'the delegate should match the method signature
Private Sub TimerEnable(ByVal enable as Boolean)
Timer1.Enabled = enable
End Sub
and then in your thread procedure
然后在你的线程过程中
Public Function CanPortOpen(ByVal HostName As String, ByVal Port As Integer) As Boolean
Dim TCP As New System.Net.Sockets.TcpClient
Try
TCP.Connect(HostName, Port)
Catch
End Try
If TCP.Connected = True Then
CanPortOpen = True
TCP.Close()
Me.Invoke(New dlgTimerEnable(AddressOf TimerEnable), New Object() {True})
Else
CanPortOpen = False
TCP.Close()
Me.Invoke(New dlgTimerEnable(AddressOf TimerEnable), New Object() {False})
FTPup.Abort()
End If
End Function
Here Invokecauses the method to be executed on the thread that owns Timer1(assuming this is a method in your form where Mewould refer to your form). The arguments are passed as an object.
HereInvoke导致该方法在拥有的线程上执行Timer1(假设这是您表单中的一个方法,其中Me将引用您的表单)。参数作为对象传递。
You can even do this as a general way to work with any timer, for example :
您甚至可以将其作为使用任何计时器的一般方法,例如:
Delegate Sub dlgTimerEnable(ByRef tmr As Timer, ByVal enable As Boolean)
Private Sub TimerEnable(ByRef tmr As Timer, ByVal enable As Boolean)
tmr.Enabled = enable
End Sub
and then :
进而 :
Me.Invoke(New dlgTimerEnable(AddressOf TimerEnable), New Object() {Timer1, True})
This makes your delegate general - you can pass it any timer and enable/disable it.
这使您的委托变得通用 - 您可以将任何计时器传递给它并启用/禁用它。

