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

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

Activating timer from another thread

vb.netmultithreadingtimerftp

提问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.

这使您的委托变得通用 - 您可以将任何计时器传递给它并启用/禁用它。