2017-07-13 18 views
0

winformプログラムでバックグラウンドワーカーを使用しています。またsomedevices
私は作品のバックグラウンドワーカースレッドを停止しようと停止ボタンを持っていますが、時々、バックグラウンドワーカースレッドが状態のまま'aborted'状態のスレッドを破棄します。

「中止」

と通信して、私は私が世話をすることを言及する必要があり

...いくつかのコードを上昇し、また、私は、すぐに緊急ボタンのようなものがスレッドを停止する必要があるデバイス

との通信を停止するには「最後に」ブロックを使用例外:

Private Sub BtnStopTest_Click(sender As Object, e As EventArgs) Handles btnStopTest.Click 
     Try 

      stoppedTesting = True 
      Log("Stopping operations safely. (You might have to wait some time)", Color.Blue, New Font("Microsoft Sans Serif", 9, FontStyle.Bold)) 

      If bgWorkThread IsNot Nothing Then 
       'stop thread 

       'if thread is sleeping (waiting for a time) 
       If bgWorkThread.ThreadState = ThreadState.Background + ThreadState.WaitSleepJoin Then 
        bgWorkThread.Interrupt() 
       Else 'if thread is working normally 
        bgWorker.CancelAsync() 
        tEO.DoWorkEventArgs.cancel = True 
        bgWorkThread.Abort() 
        'sometimes, here the Thread has state 'Aborted 

       End If 
      ElseIf bgWorkThread Is Nothing Then 
       Dim ee As New System.ComponentModel.RunWorkerCompletedEventArgs(New Object, Nothing, False) 

       BgWorker_RunWorkerCompleted(New Object, ee) 

      End If 
     Catch ex As Exception 
      Utils.PreserveStackTrace(ex) 
      Log("Error when stopping testing" & vbCrLf & Utils.ReadException(ex), MessageType.ErrorMessage) 
     End Try 
    End Sub 





    Private Sub BgWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgWorker.DoWork 
     Try 

     'some other things to do 
     For Each testStep In stepList 

       Try 
       'main operations and communication with device 
       ' below functions are all different 
       'something like: 
       'CommunicationWithDevice1() 
       'CommunicationWithDevice2() 
       'CommunicationWithDevice3() 
       'CommunicationWithDevice4() 
       '.... 
       'CommunicationWithDevice20() 

       Catch ex As Exception When TypeOf ex Is ThreadAbortException OrElse TypeOf ex Is ThreadInterruptedException 
        Utils.PreserveStackTrace(ex) 
        Log("Exception in thread" & vbCrLf & Utils.ReadException(ex), MessageType.ErrorMessage) 

        e.Cancel = True 

        If ex.GetType = GetType(ThreadAbortException) Then Thread.ResetAbort() 
        If stoppedTesting Then Exit For 

        Catch ex As Exception 
        If stoppedTesting Then Exit For 
       End Try 

       Catch ex As Exception When TypeOf ex Is ThreadAbortException OrElse TypeOf ex Is ThreadInterruptedException 
      e.Cancel = True 
      Log("Background worker thread was interrupted!") 
      Log("Background worker thread was interrupted!", Color.Red, New Font("Microsoft Sans Serif", 9, FontStyle.Bold)) 
     Catch ex As Exception 
      Utils.PreserveStackTrace(ex) 
      Log("Error when doing background work!" & vbCrLf & Utils.ReadException(ex), Color.Red, New Font("Microsoft Sans Serif", 9, FontStyle.Bold)) 
     Finally 
      StopCommunication() 
     End Try 
    End Sub 
  1. スレッドを完全に破壊するにはどうすればよいですか?
  2. 可能性がない場合は、すぐに私の 'DoWork'メソッドを終了する回避策はありますか?
+0

おっと! BgwはPoolスレッドを使います。あなたはそれのプロパティを変更してはならず、Abort()もしないでください! –

+0

スレッドを破棄したり破棄したりすることはできません。彼らは自分自身を見ます。 –

+0

@HenkHolterman ok ...スレッドの緊急停止のアイデアはありますか? –

答えて

0

BackgroundWorker.CancelAsync()あなたがBackgroundWorker.isCancellationPendingを確認することができますよう、すぐにスレッドをキャンセルしていない、それは実際にあなたがすぐにキャンセルしたい場合は、あなたがグローバルブールを持つことができ、trueに設定されているキューにSTOPメッセージをポストし、スレッドをキャンセルできる場合に設定します。 Do_Work()メソッドではブール値を定期的にチェックし、設定されている場合はExit Subを実行します。このような

何かがこれはきれいにのBackgroundWorkerを停止し、あなたがRunWorkerCompletedルーチンを実行できるようになります

Else 'if thread is working normally 
        cancelThread = true 
        tEO.DoWorkEventArgs.cancel = True 

とあなたのDo_Workサブ内

For Each testStep In stepList 

       Try 
       If cancelThread Then 
       Exit Sub 

を行う必要があります。その中でcancelThreadを確認して、BackgroundWorkerが正常に実行されたか、または中止されたかどうかを知ることができます。あなたのコードをもう一回行く後

UPDATE 2

、なぜあなたはBackgroundWorkerのを使用して、一緒にスレッドする必要がありますか?即座に取り消したい場合は、スレッドのみを使用してください。また、関数全体に対してTRY..Catchを1つだけ必要とするだけで、スレッドが確実に終了します。 (あなたが中止に関係している場合)あなたはいつも

Dim myThread As Thread = new Thread(new ThreadStart(yourFunctionForCommunication)) 
myThread.Start() 

そして、あなたの機能であなたのためのリソースを解放するの世話をする何とガベージコレクタにスレッドを割り当てることができます

Try 

.. Do your work 


Catch Ex As ThreadAbortException 
Exit Sub; 
Finally 
//Do your cleanup code here 
End Try 

中止コール

myThread.Abort() 
While mythread.ThreadState <> ThreadState.Aborted 
End While 
myThread = Nothing 

しかし、スレッドを中止することは安全なプロセスではないことを警告する必要があります。このMSDN Postを参照してください。

バックグラウンドワーカーを使用したい場合は、List<dynamic>を調べることをおすすめします。Communicatewithdevice1()....to 20()をすべて追加して、それをループで使用して、If条件を20回書く必要はありません。投稿を参照してくださいHere

+0

はい..私はこの方法を考えていましたが、実際にはチェックを使ってバックグラウンドワーカーのスレッドを汚染しています...デバイスとの通信のたびに、20〜30のチェックがあるかもしれないと想像してみてください。緊急出口... –

+0

あなたはそれをどのように汚染していると呼びますか? @eltigre –

+0

意味何度もチェック部分を書く必要があります。 –

関連する問題