Re: Threading WinForm



Hmmm, not sure if I agree with this Nicholas.

<inline>

----- Original Message ----- From: "Nicholas Paldino [.NET/C# MVP]" <mvp@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
Newsgroups: microsoft.public.dotnet.languages.csharp
Sent: Friday, February 22, 2008 1:27 PM
Subject: Re: Threading WinForm


There are a few things missing from this example. The first is that if you are calling BeginInvoke, then you should have a corresponding call to EndInvoke (as per the documentation in regards to this particular asynchronous pattern).

The only case in the API that am aware of where you call BeginXXX and do *not* have to call EndXXX is in the case of Control.BeginInvoke. This was confirmed by the winforms team some time ago (although exactly where escapes me for now)


BeginInvoke will make the posting of the windows message which causes the call in the UI thread asynchronous. Execution will return immediately after the call, and you can ^not^ assume that the delegate was called at that point (unless you interface with the IAsyncResult instance passed back from BeginInvoke).

The question here is why does the back ground thread care if the UI update has taken place of not at this point. There may be examples where it does but I can;t think of one off the top of my head.


Calling the Invoke method circumvents this, as it will wait until the UI thread processes the delegate, and in this situation, is the better option, IMO.


The only case where Control.Invoke was preferential that I came across was with the tablet Ink API that meant you could end up with unresolvable synchronization issues if you didn;t serialize the UI update with background thread work. In most cases you potentially leave yourself unecessarily open to deadlocks as you are wait for other threads to do things that you're not dependent on.

Just my $0,02

Regards

Richard Blewett
DevelopMentor
http://www.dotnetconsult.co.uk/weblog2



--
- Nicholas Paldino [.NET/C# MVP]
- mvp@xxxxxxxxxxxxxxxxxxxxxxxxxxx

"Mufaka" <mufaka@xxxxxxxxxx> wrote in message news:Equvj.15409$H05.10413@xxxxxxxxxxxxxxx
You need to use BeginInvoke to marshal back to the ui thread.

Something like this (haven't compiled / typed in ide)

private delegate void AddItemDelegate(string text);

private void AddItem(string itemText)
{
if (lbList.InvokeRequired)
{
lbList.BeginInvoke(new AddItemDelegate(AddItem, new object[] { itemText }));
}
else
{
lbList.Items.Add(itemText);
}
}

Your thread will call AddItem

ajk wrote:
I am confused, I come from Win32 and am now trying to learn C#
threading

I have a simple winform with a button, in the button's eventhandler I
create a thread, I want the thread to report progress to the form i.e.
writing a line in a list box, but the app throws an exception
complaining about the listbox being in another thread. Fine, but how
do solve this in the simplest manner?

Here is some of the code:

in the button event handler I start the thread
...
Thread workerThread = new Thread(SimulatedClient);
workerThread.IsBackground = true;
workerThread.Name = "My Thread";
workerThread.Start(this); // the form instance passed
as argument
...

in the form I have a listbox say 'lbList'

the thread function is declared as (not sure if using static is needed
here)

private static void SimulatedClient(Object objParent)
{
MyFormClass mfc = (MyFormClass)objParent; // getting the
form instance
... do some stuff ...
mfc.Items.Add("Some Msg"); <-- gives the exception
}

All of the above is in the same form class.

I have looked at delegates and events a bit but the coin hasn't fallen
down yet :) In Win32 I would for instance send a message from the
thread to the main window, how is this done in C#/.NET?

Thanks in advance.
Anders.



.


Loading