[dba-VB] Background worker threads

Shamil Salakhetdinov shamil at smsconsulting.spb.ru
Wed Apr 30 13:06:29 CDT 2008


John,

Please read the article I referred already:

"Simple and Efficient Multi-threading with Blocking Queues" 

http://www.dotnetjunkies.com/Tutorial/D7E688B8-0BDD-4D44-9A0F-4CD26FB35F51.d
cik

I think it is "what doctor ordered" for your task, and it has code, C# but
you can convert it if needed using free converters....

As for collections and variables - they are not thread safe by default.

Read these two articles (they have sample code):

"Static & Thread Safety: Part I and II"
http://www.odetocode.com/Articles/313.aspx 
http://www.odetocode.com/Articles/314.aspx 

I believe the only book you need now is the one I have also mentioned
already:

"C# Threading Handbook  by Tobin Titus et al.", ISBN:1861008295 APress, 2004
- it has a lot of code samples (C# sorry) and very good .NET multi-threading
features coverage


And this is an excerpt from MSDN on collections (MSDN is our best friend!):

+++
Collection Object (Visual Basic) 

Caution  
Iterating through a Visual Basic Collection is not a thread-safe procedure.
Even if the collection is synchronized, other threads can still modify the
collection, causing the enumerator to throw an exception. To guarantee
thread safety during enumeration, either lock the collection or catch the
exceptions resulting from changes made by other threads. For more
information on locking a programming element, see SyncLock Statement.
----

The referred above as "what doctor ordered for your task" article uses
.NET's Queue class - here is the info on it from MSDN on thread safety:

+++
Queue Class 

Thread Safety
Public static (Shared in Visual Basic) members of this type are thread safe.
Any instance members are not guaranteed to be thread safe.

To guarantee the thread safety of the Queue, all operations must be done
through the wrapper returned by the Synchronized method.

Enumerating through a collection is intrinsically not a thread safe
procedure. Even when a collection is synchronized, other threads can still
modify the collection, which causes the enumerator to throw an exception. To
guarantee thread safety during enumeration, you can either lock the
collection during the entire enumeration or catch the exceptions resulting
from changes made by other threads.
----

The "Simple and Efficient Multi-threading with Blocking Queues" article has
sample code, which shows what simple coding is needed to implement
thread-safe collections and queues...

HTH,
Shamil

-----Original Message-----
From: dba-vb-bounces at databaseadvisors.com
[mailto:dba-vb-bounces at databaseadvisors.com] On Behalf Of jwcolby
Sent: Wednesday, April 30, 2008 9:17 PM
To: Discussion concerning Visual Basic and related programming issues.
Subject: Re: [dba-VB] Background worker threads

Shamil,

I have no dispute with Charlotte, other than perhaps her response didn't 
really tell me anything.

But that brings up an good question - "one but good".  All of my books 
(each one of them) has exactly one to 1.5 pages of working with 
BackGroundWorker.  This is precisely my problem, that they all want to 
do the same "increment a number and call a progress event" example.  How 
about 4 different threads, all asynchronous processes, each of them 
handing off work to another thread (or multiple threads).  THAT is real 
life.

I have a process that reads and parses data.  There is no way to predict 
how long that will take.  However long it takes it needs to feed another 
process that performs the next step, in this case writing it back to the 
database.  There is no way to know how long that step will take.  One 
thread needs to write to a queue, the next thread needs to read from the 
queue.  Potentially that step needs to write to a new queue which is 
read by a third thread.

So what book handles this subject in depth?  AFAICT your code uses 
threads directly, correct?  Not a backgroundWorker object?  I do NOT 
want to jump off of that bridge just yet.

Just a quick question though, no one is answering whether one thread can 
WRITE to a variable and another thread READ from that variable.  Are 
variables thread safe?  Are collections thread safe?  If so then I can 
at least pass off the data class between the two threads by a collection 
in the middle.

John W. Colby
www.ColbyConsulting.com


Shamil Salakhetdinov wrote:
> John,
> 
> Sorry, I'm jumping in your dispute with Charlotte - just wanted to note
that
> the fact that "The basic code WAS working before I carved it out into a
> worker." doesn't mean that the same code (copied & pasted) into
> multi-threading environment will work OK - very often the opposite will be
> the truth - it could produce (very) faulty solution in multi-threaded
> environment, which will not be easy to sort out into properly running
> multi-threaded code...
> 
> I'd dare to advise you to prepare and test your code in VS console
> application (or .net console app as test-bed app and .net classlib(s)
> keeping all your non-UI code), and when that will work OK then add some
more
> code to run your classlibs with your .NET WinForms application: you have a
> lot to do, to learn and to test - multi-threading and .NET programming
can't
> be "captured by attack" - it's a painful and lengthy natural process,
which
> usually takes a lot of time - I know that from my own experience and
> experience of others - and better not "read all that books" - find just
one
> but good and then experiment a lot on your own - then you'll get it
working
> properly and you'll teach all of us here - I'm quite sure about that
latter!
> 
> 
> Thank you.
> 
> --
> Shamil
> 
> 
> -----Original Message-----
> From: dba-vb-bounces at databaseadvisors.com
> [mailto:dba-vb-bounces at databaseadvisors.com] On Behalf Of jwcolby
> Sent: Wednesday, April 30, 2008 8:05 PM
> To: Discussion concerning Visual Basic and related programming issues.
> Subject: Re: [dba-VB] Background worker threads
> 
> Charlotte,
> 
> Could you be a little more verbose?
> 
> I have spent about 6 hours now Googling and reading EXACTLY the same 
> (though written by different authors) code "the button starts the 
> thread, the thread increments the number, the thread raises its event 
> and passes a "percent done" to the form where it is used to update a 
> progress bar".
> 
> Give me a break!
> 
> To be honest I am astonished that FORTY different people thought that it 
> was necessary to publish identical content articles.  None of which 
> answers either of my questions.
> 
> I have a class.
> 
> The class has TWO BackgroundWorker objects defined Withevents.
> 
> bgwParseData is running a function that creates a class to load data 
> from a SQL server, and once loaded, parse that data.  The basic code WAS 
> working before I carved it out into a worker.
> 
> bgwUpdateData is running a method of a class that updates data back to 
> SQL Server.  The basic code WAS working before I carved it out into a 
> worker.
> 
> So... a single data class, two methods, one reads / parses the data in 
> an ADO DataTable, the second writes the datatable back to SQL Server.
> 
> Two threads, bgwParseData generates the data class and calls the 
> read/Parse method, then stores the class in a collection.  bgwUpdateData 
> watches the collection, pulls the class out and calls the update method.
> 
> Or that is the theory.  I have asked whether it is legal for one 
> background worker to write to a collection while a second background 
> worker reads that collection.  No answer so far.
> 
> The second issue is how can bgwParseData update THREE different text 
> boxes on the main form.  All of the examples show a cute "progress bar". 
>   I don't want a progress bar, I want THREE text boxes to display data 
> from the process running in the background worker.
> 
> I know that I can create events and raise them, and I DID THAT before I 
> started converting to backgroundworkers.  That was easy.  HOWEVER the 
> way I read it I can't raise those same events from the BackgroundWorker 
> thread because the event sink updates a physical control on the form, 
> and that is a no-no from a thread.
> 
> Unfortunately, as always happens with the books, they don't discuss 
> anything more complicated than incrementing a number and passing that 
> number back to a progress bar on the form.  I have seen that (almost) 
> identical code in probably FORTY different articles on using the 
> backgroundworker.  All saying EXACTLY the same, useless (to me) thing.
> 
> Sigh.
> 
> John W. Colby
> www.ColbyConsulting.com
_______________________________________________
dba-VB mailing list
dba-VB at databaseadvisors.com
http://databaseadvisors.com/mailman/listinfo/dba-vb
http://www.databaseadvisors.com




More information about the dba-VB mailing list