简体   繁体   中英

Nth call to backgroundworker spawns N events

I have a Sub that dims a backgroundworker each time it's called. The dowork function of the background worker does a call for data via socket connection code contained in a dll that connects to a server. The return from the server is then wrapped in an event that the socket dll raises and an eventhandler called RequestResult(see below) on the main UI thread listens for. As I repeatedly call the sub with the backgroundworker in it I go from getting one event response firing on RequestResult to multiple events like this:

Call #1: 1 event returned

Call #2: 2 events returned

....

Call #N: N events returned

It's important to note that I did NOT have this behavior prior to adding backgroundworker to the sub.

Here's simplified code of what I am doing:

Public Sub RequestData(ByVal args As object)

Dim bw As BackgroundWorker = New BackgroundWorker
AddHandler bw.DoWork, AddressOf bw_DoWork
bw.RunWorkerAsync(args)

End Sub

Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)

Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
Dim args As SocketArgs = e.Argument

    RequestServerData(args) 'This calls server thru socket connection dll


End Sub

Data is then received from server at some point and wrapped in an event that a control on the main UI thread listens for:

'Event handler on the UI thread for event containing serverdata. It fires N times.
Private Sub RequestResult(e As SocketsArgs)
If Not Me.CheckAccess Then
  Dispatcher.Invoke(Sub() Me.RequestResult(e))
  Exit Sub
End If

'Do stuff with data

 End Sub

I feel like I am missing something fundamental about BackGroundWorker, about how it fundamentally works with the threadpool. Should I not be re-diming it each time (ie have it be a class level var)? Does it spawn a thread for each call to dowork or does it stack them all up on one thread? Do I need to dispose of backgroundworker to keep multiple events from firing?

I had a similar problem (using visual studio 2015, asp.net, vb) and it was driving me crazy, but in the end I narrowed it down to what I can only call an undocumented feature of visual studio... I had

Dim WithEvents RepWorker as BackgroundWorker

RepWorker = DirectCast(Session("ReportWorker"),Backgroundworker))
if RepWorker is nothing then
    RepWorker = new BackgroundWorker
    AddHandler RepWorker.DoWork, AddressOf RepWorker_MakeReport
    Session("ReportWorker") = RepWorker
end if
RepWorker = DirectCast(Session("ReportWorker"),Backgroundworker))
RepWorker.RunWorker(.....)

and later I had the routine

Sub RepWorker_MakeReport(...) handles RepWorker.DoWork
....
End Sub

The calls to the RepWorker_MakeReport were increasing and increasing even though tracing on the raise event was showing the event was triggered only once.

After tearing what was left of my hair out, and moving the code between different segments and even trying to add in RemoveHandler calls, I finally removed the AddHandler completely and expected an error but didn't get one, instead the routine was called correctly once the first time, but then still increased the second and third time etc etc.

Finally I sussed it.... I removed the "handles RepWorker.DoWork" from the sub definition and then suddenly everything started behaving as expected.

So the moral of this story, is if you are using BackgroundWorkers and you want reliable control of the event handlers, then define them yourself and do not include the "handles" directive after the sub definition.

Good luck...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM