Question

I'm trying to figure out the best way to approach this.

I have a BackgroundWorker which is being used to make a socket connection on a timer.

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

I want to start the BackgroundWorker thread which establishes a TCP connection, reads/write some data and then close the connection and repeat every 2 seconds.

I want to physically open/close the connection each time because from time to time the server I'm connecting to doesn't send data and the readByte call halts waiting for data and the process can't continue until I reset the program (hence wanting to use a different thread to my UI).

At the moment I'm trying to use a DispatcherTimer with an Interval of 2 seconds to call Worker.RunWorkerAsync. When RunWorkerAsync is called, the DoEvents method runs - this is working ok for the first time but on subsequent DispatcherTimer tick's I'm finding the previous thread isn't closing so when calling RunWorkerAsync I'm getting

"This BackgroundWorker is currently busy and cannot run multiple tasks concurrently"

What is the best way I can achieve this?

Is there a better way?

edit: thinking about it. It would be good if I could somehow build a watchdog into it, so if the BackgroundWorker thread is found to be running for more than 2 seconds, it's terminated as this would indicate the thread has been held up by the tcp connection.

Ben

Was it helpful?

Solution

The BackgroundWorker.CancelAsync doesnt really auto-cancels the worker but that is just a flag which comes into ther DoWork(object sender, DoWorkEventArgs e) call as e.Cancel = true and \ or BackgroundWorker.CancellationPending so that a code condition can check it and return from the DoWork() thereby manually cancelling the work itself.

This is what MSDN says...

The worker code should periodically check the CancellationPending property to see if it has been set to true.

For the auto-cancellation there is Thread.Abort() call, but it may throw a ThreadAbortException. So be ready to try \ catch AllUsersWorker.RunWorkerAsync() call.

OTHER TIPS

To know if the worker is not available you can check the property: IsBusy

So when the timer ticks for the second time, you could just check if the first one is busy (in which case you can cancel it by using CancelAsync) and run a new one.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top