2013-08-07 3 views
1

Таким образом, целью этого является проверка соединения ftp-сервера, и если ftp встал, включите таймер 1. Я прочитал, что потоки не работают синхронно, и это вызывает проблему. Без потока он отлично работает, но программа зависает и перестает отвечать постоянно.Активация таймера из другого потока

Как я могу активировать таймер из другого потока? Может быть, вызов и делегирование будут работать? Но я не знаю, как это сделать.

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 
+0

Почему вы хотите, чтобы все эти таймеры здесь вообще? Вам нужно время задержки между проверкой того, что TCP-соединение можно открыть и запустить загрузку? Почему все эти разные потоки? Почему бы просто не начать поток, который загружает и сообщает о прогрессе, успехе или неудаче? –

+0

@J ... Да, таймеры предназначены для задержки. Если оба они находятся в одном потоке, это означает, что я не могу изменить интервалы? Хотя я все еще изучаю все, поэтому, возможно, это не лучший подход. – rip2444

+0

... так что вы хотите проверить, что соединение можно сделать, а затем запустить загрузку после ожидания? Я нахожу это странным обстоятельством.Нить может спать, в любом случае, если вам нужно, чтобы подождать некоторое время. Однако нет причин, почему TCP-соединение нуждается в отдыхе, прежде чем вы сможете снова открыть его. –

ответ

1

Я думаю, прежде чем вы начнете получать слишком глубоко нитками, вы должны начать, глядя на BackgroundWorker компонента. Вы можете найти его на панели инструментов в дизайнере и оставить его в своей форме. Это дает вам несколько событий

DoWork - подключить это событие с тем, что вы хотите сделать в фоновом потоке

RunWorkerCompleted - подключить это событие для запуска кода в главном (UI) поток, срабатывает, когда поток завершается , Код здесь может взаимодействовать с объектами пользовательского интерфейса как обычно.

Есть другие события, которые позволяют сообщать о прогрессе в ваш основной поток и т. Д. Цель компонента BackgroundWorker - упростить простые задачи многопоточности.

Документация ->here

See ->here примеры того, как передать данные из рабочего потока в основной поток, используя 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}) 

Это делает ваш генеральный делегат - вы можете передать его любой таймер и включить/отключить его.

+0

Я посмотрю на рабочего, но пока об альтернативе: в нем говорится, что «Invoke» не является членом ' System.Windows.Forms.Timer. Это, вероятно, ошибка нообма, но все же ... – rip2444

+0

@ rip2444 Извините, я только что исправил это - я набрал его в спешке и забыл, что «Таймер» не является контролем. Приведенный выше код должен работать. –

+0

Просто протестирован, альтернатива работала нормально, определенно будет также искать компонент BackGroundWorker. Спасибо за помощь! – rip2444

Смежные вопросы