BackgroundWorker.ReportProgress() Output Issue

R

ray.ackley

Hello all,

I have an app that uses a BackgroundWorker() object to read USB data
that is being fed in serially (FT245R chip, www.ftdichip.com). It
looks just like a serial data stream. Anyhow, it reads in the bytes
and finds the header and footer and pulls packets out of the data
stream. Nice, easy stuff. It then stuffs the packet into into a
class I made up to pull the data out through the ProgressChanged
event. The class is pretty simple, consisting of the following:

Public Class WorkerReturn
Public FullPacketBytes, PayloadSize As Integer
Public FullPacket(256) As Byte
Public Payload(256) As Byte

Public Sub WorkerReturn()
FullPacketBytes = 0
PayloadSize = 0
FullPacket.Initialize()
Payload.Initialize()
End Sub
End Class

So the BackgroundWorker passes the object out through the
ReportProgress method. This raises the ProgressChanged event:

Private Sub ReadUSBWorker_ProgressChanged(ByVal sender As Object,
ByVal e As ProgressChangedEventArgs) _
Handles ReadUSBWorker.ProgressChanged

Dim WkrRtn As WorkerReturn
WkrRtn = e.UserState

ProcessPacketType(WkrRtn)
End Sub

So far so good. All the main logic code worked just dandy, but when I
tried outputting some debug data (sent through the USB stream) to a
TextBox I got "slurred" output, apparently because the textbox takes a
while to update & redraw.

My input stream is giving me test packets whose payload simply
increments in number from 0 to 63. I can debug inside the
BackgroundWorker, and it is seeing the input and processing it 100%
correctly. The output SHOULD look like:

" 1
2
3
4
5
6
7"

etc.. But it showed up as:

" 5
5
7
10
10
10
12
12"

etc. I finally figured out that even though it's passing the object
ByVal through the ProgressChanged event (ByVal e As
ProgressChangedEventArgs), which SHOULD be making a distinct copy of
the object each time it calls it, there is some kind of threading
issue going on here with the object. When I change the
ReportProgress() call from:

worker.ReportProgress(0, WkrRtn)

To:

worker.ReportProgress(0, WkrRtn)
Thread.Sleep(100)

The numbers show up sequentially, just like they should.

Obviously I don't want to leave a 100ms delay in there, and timing on
slower computers could be a real issue. Does this make sense? Need
to see more code maybe? Any ideas?

Thanks,
Ray
 
R

RobinS

I don't think ByVal is working the way you think it is. When used with
value types (numerics like integer and double, and structures), it makes a
copy and sends it in. When used with reference types (classes, objects,
strings, etc.), it makes a copy of the *reference* to the object and sends
in the reference, not a copy of the object.

Does this information help you?

Robin S.
-----------------------------------------------
 
R

ray.ackley

Hmm, yes that does help. It sounds like I need to implement a copy
function within the class and copy it to a new instance every time its
progress is reported.
 
R

RobinS

You're going to want to implement ICloneable. If you create a new instance
and try to manually copy the data from one to the other by doing
new.Product = old.Product, if the type is a reference type, it will copy
the reference. (I know, grrrrr.) If they are value types, it will be okay.
Check out ICloneable and the Memberwise method of clone.

Robin S.
----------------------------------
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top