Async main-thread method execution

T

Tomaz Koritnik

Is it possible to asynchronously call a method from worker thread so that
this method would execute in main-thread? I'm doing some work in worker
thread and would like to report progress to main thread to update some
controls. But I'd like to do that asynchronously so that worker thread would
not block until main thread finished updating and refreshing controls which
take some time. Using invoke is out since it blocks worker thread until
method finishes.

regards
Tomaz
 
L

Laura T.

Use ThreadPool to execute whatever you need, like
System.Threading.ThreadPool.QueueUserWorkItem(delegate { OnEvent(X); });
 
W

Willy Denoyette [MVP]

Tomaz Koritnik said:
Is it possible to asynchronously call a method from worker thread so that this method
would execute in main-thread? I'm doing some work in worker thread and would like to
report progress to main thread to update some controls. But I'd like to do that
asynchronously so that worker thread would not block until main thread finished updating
and refreshing controls which take some time. Using invoke is out since it blocks worker
thread until method finishes.

regards
Tomaz

Use BeginInvoke instead of Invoke!

Willy.
 
T

Tomaz Koritnik

To Laura T. also...

You didn't understand my question. I'm already executing some work in a
background thread but I would like to execute a method in main-thread.
Myexample: worker thread has some data which has to be displayed. I must not
update controls from this thread, so I must somehow pass this data to
main-thread. And I wan't to do this async so worker thread continues working
while controls are updated. In Win32 the perfect solution to this is to send
message. Get my point now?

regards
Tomaz
 
W

Willy Denoyette [MVP]

Tomaz Koritnik said:
To Laura T. also...

You didn't understand my question. I'm already executing some work in a background thread
but I would like to execute a method in main-thread. Myexample: worker thread has some
data which has to be displayed. I must not update controls from this thread, so I must
somehow pass this data to main-thread. And I wan't to do this async so worker thread
continues working while controls are updated. In Win32 the perfect solution to this is to
send message. Get my point now?

Yes, I got your point and that's exactly what I meant, from your worker thread you need to
call Control.BeginInvoke and pass it a delegate who's method will execute on the UI thread.
Check the docs for more info and samples.

Willy.
 
N

not_a_commie

You didn't understand my question. I'm already executing some work in a
background thread but I would like to execute a method in main-thread.
Myexample: worker thread has some data which has to be displayed. I must not
update controls from this thread, so I must somehow pass this data to
main-thread. And I wan't to do this async so worker thread continues working
while controls are updated. In Win32 the perfect solution to this is to send
message. Get my point now?

I think that they did understand. Whenever you create a control/form/
someUIpiece, the thread that is created on becomes the UI (aka, main)
thread. When you want to add children to a control, they have to be
created in the same thread as their parent. Whenever you want to call
some property or method on a control, you have to make that call from
the thread where the control was created. To make this easy, the base
class for all controls and forms has Invoke and BeginInvoke methods.
You can call those functions from any thread (and same with the
Invalidate function). You pass the invokers a (delegate) function to
be called from the control's thread. BeginInvoke is asynchronous.
Invoke is synchronous (aka, blocking).

BTW, sending messages is certainly not the best solution; it's a pain
in the ars. I'm glad that .NET and SWT support these other invoke
methodologies.
 
G

Guest

In .Net 2.0, take a look at BackgroundWorkerProcess. This provides a
simplified model for asynchrous processing with notification via the
asyncresult back to the main thread.
Peter
 
N

not_a_commie

In .Net 2.0, take a look at BackgroundWorkerProcess.

Known in the help as "BackgroundWorker Control".
 
T

Tomaz Koritnik

No, again, not my point. read my post again please. Yes It's possible to use
Invoke to execute in main thread, but this will block worker thread until
method in main thread returns. As far as I know, using invoke is synchronous
process. That's exactly what I don't want. I want async call so that worker
thread continues WHILE main thread updates controls.

regards
Tomaz
 
T

Tomaz Koritnik

It's not exactly what I want. I can't use control's invoke since I don't
have any controls at the beginning. I want to call some function iside some
class that is not a control. More, it actually has nothing to do with
controls because this is an app lower layer where UI elements are not
present (and not even accessible). I may not even have an UI (service).

Therefore, again, I need to call some method in some class (that is NOT a
control) to execute in main thread.

regards
Tomaz
 
M

Marc Gravell

Then why specifically do you want to push back to the main thread? One
option may be to roll a simple delegate queue on the main thread (i.e.
so that it is pumping)? But that suggests that this main loop isn't
doing anything else useful other than being a workhorse... is that
what you desire? (if so not a problem, but it seems unusual to
deliberately serialize the workers by pushing back to a single
thread).

Marc
 
J

Jon Skeet [C# MVP]

Tomaz Koritnik said:
No, again, not my point. read my post again please. Yes It's possible to use
Invoke to execute in main thread, but this will block worker thread until
method in main thread returns. As far as I know, using invoke is synchronous
process. That's exactly what I don't want. I want async call so that worker
thread continues WHILE main thread updates controls.

If you're going to ask others to read your posts again, you should
really re-read the replies as well. Willy suggested using BeginInvoke
instead of Invoke, which is *exactly* what you're after to make it
asynchronous (which not_a_commie also pointed out in the post you were
replying to).

As for not having a control available at the time - you'd need to make
some reference available as ISynchronizeInvoke, and you would call
BeginInvoke on that. The UI would typically pass a control as the
implementation of ISynchronizeInvoke, so that the correct thread would
be used.
 
W

Willy Denoyette [MVP]

Tomaz Koritnik said:
It's not exactly what I want. I can't use control's invoke since I don't have any controls
at the beginning. I want to call some function iside some class that is not a control.
More, it actually has nothing to do with controls because this is an app lower layer where
UI elements are not present (and not even accessible). I may not even have an UI
(service).

Therefore, again, I need to call some method in some class (that is NOT a control) to
execute in main thread.

Should have said that from the beginning, anyway, I don't see why you need to execute code
on a particular thread, unless you need to access thread affinitized objects . If that's the
case, you'll have to pass a delegate to your "main thread", for instance in a queue, your
main thread will have to poll this queue or wait for a signal from the worker to pick-up the
delegate and execute it's method.

Willy.
 
Joined
Mar 21, 2009
Messages
1
Reaction score
0
Hi Tomaz,

Could you solve this problem?

I too got into the same problem.

Before showing the main form, some data is loaded in the background. once the load is done, it calls a method which creates the main form and calls show to show the main form.
But my load method which caled asynchorously returns on another thread which is not Main thread.
How can i call the main method now. If i call the main method directly, i am seeing unknown result. and in the half way everthing close.

Please give me a solution for this.

Thanks,
Rajendra prasad Racharla
 

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