473,394 Members | 1,701 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Fire event in the same thread as the UI like BackgroundWorker

This is what I've always been wondered.
Suppose I've created a class named Agent, and the Agent does some
lengthy job. Of course I don't want to block the main window, so the
Agent does the job in a separate thread. If the job is progressed it
fires an event, and the main window handled the event by changing the
value of a progress bar. The problem is that this event is fired in
another thread so when the handler in the main window tries to access
the progress bar, an exception occurs. Until now, I've been solving
this problem by checking InvokeRequired and creating a delegate.

But the .NET 2.0's built-in BackgroundWorker seems to have solved this
with a very elegant way. When a BackgroundWorker fires the progress
event, it looks like the event is fired in the same thread as the main
window, because the InvalidOperationException does not occur when I
try to access UI controls in the handler. How could this be possible?
I want my Agent class to be able to the same thing. Making a lot of
delegations in the main window code makes the code dirty.

Please give me an idea. Thank you.

Oct 21 '07 #1
4 2553
Sin Jeong-hun wrote:
[...]
But the .NET 2.0's built-in BackgroundWorker seems to have solved this
with a very elegant way. When a BackgroundWorker fires the progress
event, it looks like the event is fired in the same thread as the main
window, because the InvalidOperationException does not occur when I
try to access UI controls in the handler. How could this be possible?
I want my Agent class to be able to the same thing. Making a lot of
delegations in the main window code makes the code dirty.

Please give me an idea. Thank you.
I don't know the specifics of how BackgroundWorker does it. Since it
doesn't require a specific Control instance given to it, I suspect it's
using AsyncOperation or something similar.

I'm pretty sure it raises events on the same thread that created the
BackgroundWorker when possible (though, if I recall correctly that's not
actually what it does in a console application...it does depend on
having a message pump), not specifically the main UI thread.

You could either use AsyncOperation yourself (you'd initialize it when
your object is created, and then use it to raise events on the same
thread used to create the object). Alternatively, if your object
depends on a specific Control instance, you may find it easier to just
use the Control instance to invoke a method to raise the event.

Pete
Oct 21 '07 #2
Yes, BackgroundWorker uses AsyncOperation to marshal the call back to the
correct thread. It doesn't use a particular control thread, it simply uses
the thread that was used to create the BackgroundWorker object.

--
Browse http://connect.microsoft.com/VisualStudio/feedback/ and vote.
http://www.peterRitchie.com/blog/
Microsoft MVP, Visual Developer - Visual C#
"Peter Duniho" wrote:
Sin Jeong-hun wrote:
[...]
But the .NET 2.0's built-in BackgroundWorker seems to have solved this
with a very elegant way. When a BackgroundWorker fires the progress
event, it looks like the event is fired in the same thread as the main
window, because the InvalidOperationException does not occur when I
try to access UI controls in the handler. How could this be possible?
I want my Agent class to be able to the same thing. Making a lot of
delegations in the main window code makes the code dirty.

Please give me an idea. Thank you.

I don't know the specifics of how BackgroundWorker does it. Since it
doesn't require a specific Control instance given to it, I suspect it's
using AsyncOperation or something similar.

I'm pretty sure it raises events on the same thread that created the
BackgroundWorker when possible (though, if I recall correctly that's not
actually what it does in a console application...it does depend on
having a message pump), not specifically the main UI thread.

You could either use AsyncOperation yourself (you'd initialize it when
your object is created, and then use it to raise events on the same
thread used to create the object). Alternatively, if your object
depends on a specific Control instance, you may find it easier to just
use the Control instance to invoke a method to raise the event.

Pete
Oct 22 '07 #3
Interesting. I hadn't seen the AsyncOperation class before. It's worth
noting that it is just a wrapper for the SynchronizationContext class
though. It is the particular current SynchronizationContext (available
via SynchronizationContext.Current) that does the actual work of
marshalling to the correct thread. If you're running Winforms, it'll
be a WindowsFormsSynchronizationContext. For WPF, it'll be a
DispatcherSynchronizationContext.

So AsyncOperation makes it easier to post progress and completion of
an operation to the UI (or "contextual") thread. Cool stuff.

Kent

Oct 22 '07 #4
On Oct 23, 1:00 am, "ken...@internode.on.net"
<ken...@internode.on.netwrote:
Interesting. I hadn't seen the AsyncOperation class before. It's worth
noting that it is just a wrapper for the SynchronizationContext class
though. It is the particular current SynchronizationContext (available
via SynchronizationContext.Current) that does the actual work of
marshalling to the correct thread. If you're running Winforms, it'll
be a WindowsFormsSynchronizationContext. For WPF, it'll be a
DispatcherSynchronizationContext.

So AsyncOperation makes it easier to post progress and completion of
an operation to the UI (or "contextual") thread. Cool stuff.

Kent
Right after I posted the original post, I thought maybe disassembling
the BackgroundWorker
would give me a hint. So I did it. It used several classes I'd never
seen before, and the logic
was quite unfamilar to me. But after all, I modified my class
according to the way BackgroundWoker
works, and now it works just like the BackgroundWorker. I don't need
to use InvokeRequired every time.
I think it would be worth for other people to try this.
Thank you for your replies, all.

Oct 25 '07 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Carlo Marchesoni | last post by:
From an aspx page (A.aspx) I open another one (B.aspx - for table lookup). When the user selects an entry in B.aspx I would like to force a button's event in A.aspx to be fired. I guess the only...
3
by: nt8jbwu02 | last post by:
I am trying to use the example at: http://msdn2.microsoft.com/en-us/library/ms171728(d=ide).aspx to update a control in a thread safe maner. The article shows a couple of ways to do so and...
7
by: Jayyde | last post by:
Is there any way to accomplish this? The forms _Load event fires off several other small ones that I'd like to track time for. I can't get either the Mdi Parent form's timer _Tick event or the...
8
by: =?Utf-8?B?R3JlZyBMYXJzZW4=?= | last post by:
I'm trying to figure out how to modify a panel (panel1) from a backgroundworker thread. But can't get the panel to show the new controls added by the backgroundwork task. Here is my code. In...
5
by: redear | last post by:
Is there a way to immediately terminate a BackgroundWorker thread? My problem is that the BackgroundWorker starts with a call to My.Computer.FileSystem.GetFiles that can run for a very long time if...
8
by: =?Utf-8?B?cmFuZHkxMjAw?= | last post by:
I have an application with several BackgroundWorker threads. I hoped I'd be able to just type backgroundworker1.Name = "bw1"; but I don't see a name property. Any thoughts on how to name a...
7
by: Gary Brown | last post by:
Hi, I have a computation intensive application that tries to update the display quite often. After a few seconds the window stops updating and the window goes blank. A breakpoint in the Paint...
12
by: Steve | last post by:
Hi All, I'm a newbee in C# and have a Windows form application. The main form has a progress bar. In one of the methods of the main form, I call a class derived from Object which processes a...
27
by: cmdolcet69 | last post by:
Can anyone tell me if its possible to do multiple event args in vb.net?
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.