Solved

VB.NET Thread issue

Posted on 2011-03-12
19
501 Views
Last Modified: 2012-05-11
When a thread I started finishes, I raises an event back to the main process that the thread has completed.  One of the things I want to do in this call back is add an entry to a list box on the main form, but when the event happens I get this error:

"Cross-thread operation not valid: Control 'lbStatus' accessed from a thread other than the thread it was created on."

How can I add an entry to this list box from the finishing thread?


0
Comment
Question by:onemorecoke
  • 6
  • 5
  • 5
  • +1
19 Comments
 
LVL 17

Expert Comment

by:nepaluz
ID: 35116179
Have you implemented your custom threading or utilised the "out of the box" threading of background worker? I'd use the latter and simply add the call to UI in the process changed event.
0
 
LVL 3

Author Comment

by:onemorecoke
ID: 35116211
Here is the code involved:

=========================
Up top in the main form:

Dim t As clsThreadWritebackBatch
Dim ThreadBatch As System.Threading.Thread


=========================
The button click that creates the thread:

If ThreadBatch Is Nothing Then
                Dim t As New clsThreadWritebackBatch
                Dim ThreadBatch As New System.Threading.Thread(AddressOf t.ProcessBatch)
                AddHandler t.FinishedBatch, AddressOf FinishedBatchEventHandler
                ThreadBatch.Priority = System.Threading.ThreadPriority.BelowNormal
                ThreadBatch.Start()
End If

=========================
The callback function

Public Sub FinishedBatchEventHandler(ByVal ItemCount As Long)
...
lbStatus.Items.Add(FormatDateTime(Now, DateFormat.GeneralDate) & " - Finished")
...
end sub


0
 
LVL 12

Expert Comment

by:Mohamed Abowarda
ID: 35116312
The exception is occurring because you are calling the method FinishedBatchEventHandler() from another thread other than the main one that it was created on.

You need to use delegate to call FinishedBatchEventHandler from the main thread.
0
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
LVL 17

Expert Comment

by:nepaluz
ID: 35116368
It may be worth your while to run your rule over the following walk-through in implementing the backgroundworker as a class (out of the box threading).

http://msdn.microsoft.com/en-us/library/ywkkz4s1.aspx
0
 
LVL 12

Accepted Solution

by:
Mohamed Abowarda earned 250 total points
ID: 35116397
0
 
LVL 86

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 250 total points
ID: 35116464
I agree that the BackgroundWorker() is much easier.

Here's how to do it the manual way though:
Public Delegate Sub FinishedDelegate(ByVal ItemCount As Long)

Public Sub FinishedBatchEventHandler(ByVal ItemCount As Long)
    If Me.InvokeRequired Then
        Me.Invoke(New FinishedDelegate(AddressOf FinishedBatchEventHandler), New Object() {ItemCount})
    Else
        ' *** it's safe to update any GUI elements in this 'Else' block ***
        ...
        lbStatus.Items.Add(FormatDateTime(Now, DateFormat.GeneralDate) & " - Finished")
        ...
    End If
End Sub

Open in new window

0
 
LVL 3

Author Comment

by:onemorecoke
ID: 35117511
When you say "manual way", does that mean that the backgroundworker component is doing the same thing I am doing manually or is it a completely different thing?  I am used to in-process and out-of-process terminology.  Is what I am doing out-of-process?

Thanks
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35117532
Using the BackgroundWorker() control you don't need to use Invoke()/Delegates since the ProgressChanged() and RunWorkerCompleted() events have already been marshaled to the main UI thread for you.  So when those events are received you can simply directly update your GUI without worrying about it.

...so "under the hood" the BackgroundWorker() control is doing this kind of thing for you.  There are situations where knowing how to do it manually are beneficial as well.
0
 
LVL 3

Author Comment

by:onemorecoke
ID: 35117549
Thanks Idle_Mind!  Would you be able to show me how I could accomplish this with the BackgroundWorker() control?
0
 
LVL 12

Expert Comment

by:Mohamed Abowarda
ID: 35117579
"Cross-thread operation not valid" exception only occurs when you try to make changes on controls from another thread other than the one that it was created on.

After you add the BackgroundWorker to your form, call BackgroundWorker1.RunWorkerAsync() to start.

The BackgroundWorker support three main events:
1. DoWork:
It occur after you call RunWorkerAsync() method and it execute the code on another thread other than the main one.

2. ProgressChanged:
This event raise whenever you call ReportProgress() method and it execute the code on the main thread (you can make any change on controls using this event)

3. RunWorkerCompleted:
It occur after the whole process on DoWork is completed.
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35117588
Are you creating just ONE instance of clsThreadWritebackBatch() at a time and waiting for the results?
...or do you need lots of these things running at the same time?
0
 
LVL 3

Author Comment

by:onemorecoke
ID: 35117739
For this specific process, yes just one.  My next situation though is launching multiple threads with the same class.
0
 
LVL 17

Expert Comment

by:nepaluz
ID: 35117917
I do not know whether you dislike my advice, however, the best by far example would be the walk-through that I gave you earlier.

The walk-through shows you how to create a class implementing the background worker. It is simple and concise and its up to you how far you want to take it from there. I will give you the link again

http://msdn.microsoft.com/en-us/library/ywkkz4s1.aspx
0
 
LVL 12

Expert Comment

by:Mohamed Abowarda
ID: 35117927
@onemorecoke: Have you tried to use BackgroundWorker as I posted above?

It will solve your issue.
0
 
LVL 3

Author Comment

by:onemorecoke
ID: 35118015
Medo3337, I am experimenting to see what works best for my situation, thanks for checking in.
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35118398
The link by nepaluz does give a good example.

Basically INSIDE your clsThreadWritebackBatch() class you would encapsulate a BackgroundWorker() control and in the DoWork() handler you execute your code that is now in your manual thread.  You pass the result to the RunWorkerCompleted() event and from there you can raise you classes FinishedBatch() event.
0
 
LVL 3

Author Comment

by:onemorecoke
ID: 35119415
Ok, thanks.  Last question, just trying to decide on using a backgroundworker component or manual method.  Can you set thread priority using the backgroundworker component or is that something that I will have to use the manual method for?  Thanks everyone.

0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 35119441
Don't think you can set the priority on the backgroundworker...
0
 
LVL 12

Expert Comment

by:Mohamed Abowarda
ID: 35119516
If you want to set the thread priority you will have to use Threading class:
http://www.java2s.com/Code/VB/Thread/ThreadpriorityHighestandnormal.htm
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Since .Net 2.0, Visual Basic has made it easy to create a splash screen and set it via the "Splash Screen" drop down in the Project Properties.  A splash screen set in this manner is automatically created, displayed and closed by the framework itsel…
Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
Finding and deleting duplicate (picture) files can be a time consuming task. My wife and I, our three kids and their families all share one dilemma: Managing our pictures. Between desktops, laptops, phones, tablets, and cameras; over the last decade…

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question