Повторение задачи BackgroundWorker с использованием DistpatcherTimer - PullRequest
1 голос
/ 28 октября 2011

Я пытаюсь найти лучший способ подойти к этому.

У меня есть 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

Я хочу запустить поток BackgroundWorker, который устанавливает соединение TCP, читает / записывает некоторые данные, а затем закрывает соединение и повторяется каждые 2 секунды.

Я хочу физически открывать / закрывать соединение каждый раз, потому что время от времени сервер, к которому я подключаюсь, не отправляет данные, и вызов readByte останавливает ожидание данных, и процесс не может продолжаться, пока я не сброслю программа (следовательно, желающая использовать другой поток для моего пользовательского интерфейса).

В данный момент я пытаюсь использовать DispatcherTimer с интервалом в 2 секунды для вызова Worker.RunWorkerAsync. Когда вызывается RunWorkerAsync, запускается метод DoEvents - в первый раз он работает нормально, но при последующих тиках DispatcherTimer обнаруживается, что предыдущий поток не закрывается, поэтому при вызове RunWorkerAsync я получаю

"Этот BackgroundWorker в настоящее время занят и не может выполнять несколько задач одновременно "

Как мне лучше всего этого достичь?

Есть ли лучший способ?

редактировать: думать об этом. Было бы хорошо, если бы я мог как-то встроить в него сторожевой таймер, поэтому, если выясняется, что поток BackgroundWorker работает более 2 секунд, он прерывается, поскольку это указывает на то, что поток был задержан соединением tcp.

Ben

Ответы [ 2 ]

1 голос
/ 28 октября 2011

BackgroundWorker.CancelAsync в действительности не отменяет работника автоматически, но это просто флаг, который входит в DoWork(object sender, DoWorkEventArgs e) вызов как e.Cancel = true и \ или BackgroundWorker.CancellationPending, так что условие кода может проверить его и вернуться из DoWork() тем самым вручную отменяя саму работу.

Это то, что MSDN говорит ...

Рабочий код должен периодически проверять CancellationPending свойство, чтобы увидеть, было ли оно установлено в true.

Для автоматической отмены есть вызов Thread.Abort(), но он может выдать ThreadAbortException. Так что будьте готовы попробовать \ ловить AllUsersWorker.RunWorkerAsync() звонок.

0 голосов
/ 28 октября 2011

Чтобы узнать, если работник не доступен, вы можете проверить свойство: IsBusy

Поэтому, когда таймер срабатывает во второй раз, вы можете просто проверить, занят ли первый, (в этом случае вы можете отменить его с помощью CancelAsync) и запустить новый.

...