Solved

VB.NET Thread issue

Posted on 2011-03-12
19
463 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 17

Expert Comment

by:nepaluz
Comment Utility
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
Comment Utility
0
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 250 total points
Comment Utility
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
Comment Utility
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 85

Expert Comment

by:Mike Tomlinson
Comment Utility
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
Comment Utility
Thanks Idle_Mind!  Would you be able to show me how I could accomplish this with the BackgroundWorker() control?
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 12

Expert Comment

by:Mohamed Abowarda
Comment Utility
"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 85

Expert Comment

by:Mike Tomlinson
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
@onemorecoke: Have you tried to use BackgroundWorker as I posted above?

It will solve your issue.
0
 
LVL 3

Author Comment

by:onemorecoke
Comment Utility
Medo3337, I am experimenting to see what works best for my situation, thanks for checking in.
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
Comment Utility
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
Comment Utility
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 85

Expert Comment

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

Expert Comment

by:Mohamed Abowarda
Comment Utility
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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Microsoft Reports are based on a report definition, which is an XML file that describes data and layout for the report, with a different extension. You can create a client-side report definition language (*.rdlc) file with Visual Studio, and build g…
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

744 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now