2016-04-13 14 views
0

'daki ana iş parçacığındaki bir işlevi nasıl çağırabilirim Windows formumda çağrılan ve kullanıcı arabirimindeki bir düğme tıklandığında mükemmel şekilde çalışan bir zamanlayıcı işlevim var. Ancak, benim uygulamada bir TCP soketini kullanarak bir sunucuya bağlandığımda, sunucu bağlantıyı kopardığında, zamanaşımının (ticker) başlaması için bu noktada istisnai durumun yakalanmasını ve kimliği değiştirmemesini sağlayın ve yeniden bağlanmayı çalıştırın. Zamanlayıcıyı try catchtan çalıştırdığımda çalışmaz, bu yüzden onun ana iş parçacığı üzerinde olduğunu hayal ediyorum?Başka bir iş parçacığındaki (db)

Public Shared Sub ReceiveCallback(ByVal ar As IAsyncResult) 

     Dim state As StateObject = CType(ar.AsyncState, StateObject) 
      Dim client As Socket = state.workSocket 
      Dim strReceiveBuffer As String = String.Empty 

      ' Read data from the remote device. 
      Dim bytesRead As Integer 

     Console.WriteLine("ar to string = " & ar.ToString) 
     'While client.Connected 
     If (AsynchronousClient.connectDone.WaitOne(5000, True)) Then 
      Try 

       If client.Connected = True Then 

        bytesRead = client.EndReceive(ar) 
        Console.WriteLine("Socket Connected") 
        If bytesRead > 0 Then 
         state.sb.Clear() 
         ' There might be more data, so store the data received so far. 
         state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead)) 

         strReceiveBuffer = state.sb.ToString() 
         MainForm.main_Response = state.sb.ToString() 

         If strReceiveBuffer.IndexOf("doses-remaining") > 0 Then 
          response = state.sb.ToString() 
          MainForm.GetLabelTextToString(response) 
          'receiveDone.Set() 
          'isReceived = True 
          'Return 
         End If 

         ' Get the rest of the data. 
         client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state) 


        Else 
         ' All the data has arrived; put it in response. 
         If state.sb.Length > 1 Then 

          response = state.sb.ToString() 

         End If 
         ' Signal that all bytes have been received. 
         receiveDone.Set() 
         isReceived = True 
        End If 
       Else 
        MainForm.WriteLog("RecieveCallback() Error outside catch :" & Date.Today.ToString & " " & TimeOfDay) 
        MainForm.UpdateList("RecievecallBack error, attempting reconnect..." & client.RemoteEndPoint.ToString()) 

        MainForm.isRunning = False 
        MainForm.DroppedConnection(0) 
       End If 


      Catch ex As Exception 

       'MessageBox.Show("ReceiveCallback Error, Check Log.") 

       MainForm.WriteLog("RecieveCallback() Error inside catch :" & Date.Today.ToString & " " & TimeOfDay & ex.Message) 
       MainForm.UpdateList("RecievecallBack error, attempting reconnect..." & client.RemoteEndPoint.ToString()) 

       client.Shutdown(SocketShutdown.Both) 
       client.Close() 
       client.Dispose() 
       MainForm.isRunning = False 
       Dim d As DroppedConnectionDelegate = AddressOf MainForm.DroppedConnection 
       'MainForm.DroppedConnection(0) 
       d.BeginInvoke(0, Nothing, Nothing) 
       Exit Try 



      End Try 

     End If 
     ' End While 
    End Sub 'ReceiveCallback 
: Kamu Delegesi Sub DroppedConnectionDelegate (As Integer ByVal RECONN) İşte
Public Sub DroppedConnection(ByVal ReConn As Integer) 

    Console.Write("Dropped Connection()") 

    Thread.Sleep(1000) 
    If ReConn = 1 Then 

      MakeConnection(My.Settings.savedIP, False) 
     Else 
      isRunning = False 
      Second = 0 
      'client.Close() 
      'client.Dispose() 
      Timer1.Interval = 1000 
      Timer1.Enabled = True 

      Timer1.Start() 'Timer starts functioning 


     End If 
    ' End If 

End Sub 

Public Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick 

    Second = Second + 1 
    Console.WriteLine(Second) 
    If Second >= 10 Then 
     Timer1.Stop() 'Timer stops functioning 
     Timer1.Enabled = False 
     MakeConnection(ServerAddressString, False) 
    End If 

End Sub 

Kimliği yakalamak istisna saatini diyoruz yerden alt geçerli: Burada

zamanlayıcı için benim kodudur

Uygulamayı çalıştırırsam ve sunucu beklenmedik şekilde kesilirse, şu anda otomatik olarak yeniden bağlanmayacaktır. Bağlan düğmesini tıklatırsam (ancak zamanlayıcıyı çağırırsa) zamanlayıcıyı çalıştırır.

Herkes yardımcı olabilir mi?

Şimdiden teşekkürler

+0

Kullandığınız Timer sınıfı iş parçacığı için güvenli değildir; çalışan iş parçacığı üzerinde bulunan Start() yöntemi, umduğunuz şeyi yapmaz. Asla işaretlemeyecek. MainForm'u bu kodda kullanmak da yanlıştır, hiçbir zaman bir şey göremezsiniz. –

cevap

1

içinde ben hiç denemedim olarak% 100 emin değilim ama ne yaptığını daha sonra Windows.Forms.Timer yerine Timers.Timer kullanırsanız şimdi çalışacağını düşünüyorum. Varsayılan olarak, Timers.Timer, Elapsed olayını ikincil bir iş parçacığına yükseltecektir, ancak kullanıcı arabiriminde olayları yükseltmek için SynchronizingObject özelliğine bir form veya başka bir denetim atayabilirsiniz. İkincil bir iş parçacığından Start numaralı telefondan arama yapılması bu durumda tamamlanmalıdır.

Bu işe yaramazsa, önce Timer'u başlatmadan önce UI iş parçacığına bir yöntem çağrısı uygulayarak istediğiniz şeyi yapabilirsiniz. Bu şu şekilde görünebilir:

Private Sub StartTimer() 
    If Me.InvokeRequired Then 
     Me.Invoke(New Action(AddressOf StartTimer)) 
    Else 
     Me.Timer1.Start() 
    End If 
End Sub 

Herhangi bir iş parçacığında bu yöntemi çağırabilirsiniz ve yalnızca çalışır.

Enabled özelliğinin ayarlanmasının ve Start veya Stop numaralı telefonların aranmasının gereksiz olduğunu unutmayın. Start zaten Enabled değerini True ve Stop, False olarak ayarlar. Birini veya diğerini, her ikisini de yapmayın. Timer'u başlatmak veya durdurmak istediğinizi bildiğinizde bir yöntemi çağırmak en uygun yöntemdir. True veya False olabilecek bir Boolean değeriniz varsa, özelliği kullanmalısınız. Mülkün bir değerin değerini kullanarak ayarlamak yanlış değildir, fakat amaçlanan şey değildir. Sadece çalışacaktır herhangi parçacığı üzerinde bu yöntemi çağıran Yine

Private Sub EnableTimer(enable As Boolean) 
    If Me.InvokeRequired Then 
     Me.Invoke(New Action(Of Boolean)(AddressOf EnableTimer), enable) 
    Else 
     Me.Timer1.Enabled = enable 
    End If 
End Sub 

: Her ikisine de başlamak için aynı yöntemi kullanın ve ikincil bir iş parçacığı gelen Timer durdurmak ne zaman özelliğini kullanmak için uygun nerede bir örnektir.

İlgili konular