2011-10-28 8 views
1

私はこれにアプローチする最善の方法を見つけようとしています。DistpatcherTimerを使用してBackgroundWorkerタスクを繰り返す

タイマーでソケット接続を行うために使用されているBackgroundWorkerがあります。

Public Shared AllUsersWorker As New BackgroundWorker 
Public Shared AllUsersWorkerTimer As New DispatcherTimer 

AllUsersWorkerTimer.Interval = TimeSpan.FromSeconds(2) 
AllUsersWorkerTimer.Start() 

AddHandler AllUsersWorkerTimer.Tick, AddressOf All_Users_Worker_Timer_Tick 

Public Shared Sub All_Users_Worker_Timer_Tick() 
    AllUsersWorker.RunWorkerAsync() 
End Sub 

Public Shared Sub AllUsersWorker_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) 

    tcpClient = New TcpClient 
    tcpClient.Connect("localhost", 9999) 

    networkStream = tcpClient.GetStream 

    If networkStream.CanWrite And networkStream.CanRead Then 
     Read_All_Connections() 
    End If 
    tcpClient.Close() 
End Sub 

は、私はいくつかのデータを書き込み/、TCP接続を確立読み込みBackgroundWorkerのスレッドを起動し、接続を閉じて、2秒ごとに繰り返したいです。

私が接続しているサーバーがデータを送信しないため、データを待っているreadByte呼び出しが停止し、プロセスをリセットするまでプロセスを続行できないため、毎回物理的に接続を開閉したいプログラム(したがって、私のUIに別のスレッドを使用したい)。

現時点では、間隔2秒のDispatcherTimerを使用してWorker.RunWorkerAsyncを呼び出そうとしています。 RunWorkerAsyncが呼び出されると、DoEvents関数メソッドが実行されます - これが初めてOK働いたが、その後のDispatcherTimer目盛りの上でされて、私は

「これを取得していますRunWorkerAsyncを呼び出すときに、以前のスレッドがそれほどクローズされていません見つけますよBackgroundWorkerは現在ビジー状態であり、複数のタスクを同時に実行することはできません 同時に "

これを達成するにはどうすればよいですか?

良い方法がありますか?

編集:考えてみてください。どうにかしてウォッチドッグを構築できればいいと思うので、BackgroundWorkerスレッドが2秒以上実行されていれば、スレッドがtcp接続によって保持されていることを示すので、終了します。労働者が利用できない場合は、プロパティを確認することができます知っている

ベン

+0

DispatcherTimerの設定方法とDoEventsメソッドの設定について説明します。 –

+0

いくつかのコードを追加しました。 – Ben

+0

Tickイベントハンドラでタイマーを停止し、RunWorkerCompletedイベントハンドラでそれを起動してください。それが意味をなさない場合は、新しいBGWを作成します(まれにしか行いません)。 –

答えて

1

BackgroundWorker.CancelAsync doesntのは本当に労働者を自動的にキャンセルするが、それは、コードの状態がそれを確認し、作業自体をキャンセルすることにより、手動でDoWork()から返すことができるようにe.Cancel = trueと\またはBackgroundWorker.CancellationPendingとしてTHER DoWork(object sender, DoWorkEventArgs e)コールに入ってくるだけのフラグであり、 。

これは... MSDNが言う

である労働者のコードは定期的にそれがtrueに設定されているかどうかを確認するためにCancellationPending プロパティをチェックする必要があります。

自動キャンセルの場合はThread.Abort()コールですが、ThreadAbortExceptionが返されることがあります。だから試着する準備ができているAllUsersWorker.RunWorkerAsync()呼び出しをキャッチします。

0

:タイマー2回目の刻みとき最初のものは、(中にビジー状態の場合IsBusy

だから、あなただけチェックできますこの場合、CancelAsyncを使用してキャンセルすることができます)、新しいものを実行します。

+0

ちょうどそれを試みた。 2度目のIsBusyはTrueですが、CancelAsyncを呼び出してもそれを殺すことはできません。 – Ben

+0

CancelAsync()は、あなたのバックグラウンドワーカーで、プロパティ "CancellationPending"をtrueに設定するだけで、そのプロパティをチェックしてDoEventsを終了するのはあなたの責任です。私はVBをしませんが、私はあなたがWeb上でたくさんの例を見つけることができると確信しています。 –

+0

キャンセルしてビジー状態になるのを待つことは機能しません。それはデッドロックと呼ばれています。 –