UI & Worker thread communication

  • Thread starter Brett Robichaud
  • Start date
B

Brett Robichaud

I'm trying to decide on the right approach for communication between the UI
and a worker thread in a WinForms app. I am very familiar with threads in
the unmanaged C++ world and in the past have used WM_USER based messages to
communicate status from the worker thread back to the UI thread. What is
the right way to do this in .Net? Are asynchronous delegates the way to go,
or is there a better (or just different) approach I should consider?

-Brett-
 
N

Nicholas Paldino [.NET/C# MVP]

Brett,

If you have a control that was created on the UI thread, then you can
just call Invoke on that control, passing a delegate and the parameters to
it, and it will call the method on the UI thread, allowing you to perform UI
operations.

It's much easier than creating your own WM_USER messages and then
handling the marshalling and the like.

Hope this helps.
 
R

Richard Blewett [DevelopMentor]

I'd argue to generally avoid Control.Invoke in favour of Control.BeginInvoke.

Invoke waits for the method pass via the delegate to have finished executing ont he UI thread before it returns, BeginInvoke does now. It is a rare situation that a background thread requires this type of interaction it also has the possibility in some situations (depending on your code) to leave you open to deadlock between the worker and UI thread.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<[email protected]>

Brett,

If you have a control that was created on the UI thread, then you can
just call Invoke on that control, passing a delegate and the parameters to
it, and it will call the method on the UI thread, allowing you to perform UI
operations.

It's much easier than creating your own WM_USER messages and then
handling the marshalling and the like.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Brett Robichaud said:
I'm trying to decide on the right approach for communication between the
UI
and a worker thread in a WinForms app. I am very familiar with threads in
the unmanaged C++ world and in the past have used WM_USER based messages
to
communicate status from the worker thread back to the UI thread. What is
the right way to do this in .Net? Are asynchronous delegates the way to
go,
or is there a better (or just different) approach I should consider?

-Brett-



---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
J

John Wood

But doesn't failing to call EndInvoke result in a memory leak?

--
John Wood
EMail: first name, dot, second name at priorganize.com


Richard Blewett said:
I'd argue to generally avoid Control.Invoke in favour of Control.BeginInvoke.

Invoke waits for the method pass via the delegate to have finished
executing ont he UI thread before it returns, BeginInvoke does now. It is a
rare situation that a background thread requires this type of interaction it
also has the possibility in some situations (depending on your code) to
leave you open to deadlock between the worker and UI thread.
Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/ said:
Brett,

If you have a control that was created on the UI thread, then you can
just call Invoke on that control, passing a delegate and the parameters to
it, and it will call the method on the UI thread, allowing you to perform UI
operations.

It's much easier than creating your own WM_USER messages and then
handling the marshalling and the like.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Brett Robichaud said:
I'm trying to decide on the right approach for communication between the
UI
and a worker thread in a WinForms app. I am very familiar with threads in
the unmanaged C++ world and in the past have used WM_USER based messages
to
communicate status from the worker thread back to the UI thread. What is
the right way to do this in .Net? Are asynchronous delegates the way to
go,
or is there a better (or just different) approach I should consider?

-Brett-



---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
W

Willy Denoyette [MVP]

This is a special case, calling EndInvoke is not required for
Control.BeginInvoke, it's only needed when calling Delegate.BeginInvoke.

Willy.

John Wood said:
But doesn't failing to call EndInvoke result in a memory leak?

--
John Wood
EMail: first name, dot, second name at priorganize.com


Richard Blewett said:
I'd argue to generally avoid Control.Invoke in favour of Control.BeginInvoke.

Invoke waits for the method pass via the delegate to have finished
executing ont he UI thread before it returns, BeginInvoke does now. It is
a
rare situation that a background thread requires this type of interaction
it
also has the possibility in some situations (depending on your code) to
leave you open to deadlock between the worker and UI thread.
Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/ said:
Brett,

If you have a control that was created on the UI thread, then you can
just call Invoke on that control, passing a delegate and the parameters to
it, and it will call the method on the UI thread, allowing you to
perform UI
operations.

It's much easier than creating your own WM_USER messages and then
handling the marshalling and the like.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Brett Robichaud said:
I'm trying to decide on the right approach for communication between the
UI
and a worker thread in a WinForms app. I am very familiar with threads in
the unmanaged C++ world and in the past have used WM_USER based messages
to
communicate status from the worker thread back to the UI thread. What is
the right way to do this in .Net? Are asynchronous delegates the way to
go,
or is there a better (or just different) approach I should consider?

-Brett-



---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
R

Richard Blewett [DevelopMentor]

Ahh now theres a good question. No it doesn't - not for *Control*.EndInvoke. For every other EndInvoke it might (Microsoft only said they reserved the right to leak not that they definitely would, and as we can't determine their implementation from SP to SP let alone version to version you must alwasy call EndInvoke apart from the Control.EndInvoke).

The problem was in terms of API naming. I asked someone from the WInforms team why they didn't rename BeginIvoke when they realised they had a clash in API names and theirs hacd different semantics from everyone elses and they said "we got there first" ... so there you go.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<#[email protected]>

But doesn't failing to call EndInvoke result in a memory leak?

--
John Wood
EMail: first name, dot, second name at priorganize.com


Richard Blewett said:
I'd argue to generally avoid Control.Invoke in favour of Control.BeginInvoke.

Invoke waits for the method pass via the delegate to have finished
executing ont he UI thread before it returns, BeginInvoke does now. It is a
rare situation that a background thread requires this type of interaction it
also has the possibility in some situations (depending on your code) to
leave you open to deadlock between the worker and UI thread.
Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog
nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/ said:
Brett,

If you have a control that was created on the UI thread, then you can
just call Invoke on that control, passing a delegate and the parameters to
it, and it will call the method on the UI thread, allowing you to perform UI
operations.

It's much easier than creating your own WM_USER messages and then
handling the marshalling and the like.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Brett Robichaud said:
I'm trying to decide on the right approach for communication between the
UI
and a worker thread in a WinForms app. I am very familiar with threads in
the unmanaged C++ world and in the past have used WM_USER based messages
to
communicate status from the worker thread back to the UI thread. What is
the right way to do this in .Net? Are asynchronous delegates the way to
go,
or is there a better (or just different) approach I should consider?

-Brett-



---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]



---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.771 / Virus Database: 518 - Release Date: 28/09/2004



[microsoft.public.dotnet.languages.csharp]
 
W

William Stacey [MVP]

Example pattern to update a richtextbox from any thread. The actual control
could be anything, just change as needed:

private delegate void UpdateDelegate(string text);

public void UpdateRTB1(string text)
{
if ( InvokeRequired )
{
UpdateDelegate ud = new UpdateDelegate(UpdateRTB1);
BeginInvoke(ud, new object[]{text});
}
else
{
this.rtbClient1.AppendText(text);
}
}

Now just call the method from either your form or any thread (your worker
will still need a ref to the form to call the method) and it does the right
thing.
 
S

Stephen Lamb

Richard Blewett said:
I'd argue to generally avoid Control.Invoke in favour of Control.BeginInvoke.

Invoke waits for the method pass via the delegate to have finished
executing ont he UI thread before it returns, BeginInvoke does now. It is a
rare situation that a background thread requires this type of interaction it
also has the possibility in some situations (depending on your code) to
leave you open to deadlock between the worker and UI thread.
Be wary of the Invoke and BeginInvoke methods on the form. If you call
either of these functions and the handle for the form has not been created,
an exception will be thrown. An exception will also be thrown if the handle
has been destroyed, maybe even before - (I haven't quite figured out the
semantics, nor do they seem to be included in the documentation. Please
anyone, correct me if I'm wrong here - I'd love to be).

Invoke can be handy for handling unrecoverable errors that occur on worker
threads. Getting the UI thread to show an error message dialog may be the
right thing to do.
 

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