1

因此,它的目的是检查 ftp 服务器的连接,如果 ftp 已启动,则启用 timer1。我读过线程不能同步工作,这就是问题所在。没有线程它工作正常,但程序挂起并停止不断响应。

如何从另一个线程激活计时器?也许调用和委托会起作用?但我不知道该怎么做。

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
4

1 回答 1

1

我认为在你开始深入了解线程之前,你应该从查看BackgroundWorker组件开始。您可以在设计器的工具栏上找到它,并将其拖放到表单上。它为您提供了几个事件

DoWork- 将此事件与您想在后台线程中完成的任何事情联系起来

RunWorkerCompleted- 连接此事件以在主 (UI) 线程中运行代码,当线程完成时触发。此处的代码可以正常与 UI 对象交互。

还有其他事件允许您向主线程报告进度等。BackgroundWorker 组件的目的是使简单的多线程任务像这样更容易。

文档是 ->这里

有关如何使用 EventArgs 将数据从工作线程传递到主线程的示例,请参见 ->此处。


或者,如果您只想从您的线程运行计时器,您可以这样做:

 '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

然后在你的线程过程中

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

这里Invoke导致方法在拥有的线程上执行Timer1(假设这是您的表单中的一个方法,Me它将引用您的表单)。参数作为对象传递。

您甚至可以将其作为使用任何计时器的通用方式,例如:

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

进而 :

Me.Invoke(New dlgTimerEnable(AddressOf TimerEnable), New Object() {Timer1, True})

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

于 2013-08-07T22:28:20.673 回答