Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / February 2008

Tip: Looking for answers? Try searching our database.

Threading WinForm

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
ajk - 22 Feb 2008 06:42 GMT
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.
Michael Nemtsev [MVP] - 22 Feb 2008 07:00 GMT
Hello ajk,

Read Jon's article http://www.yoda.arachsys.com/csharp/threads/winforms.shtml

---
WBR,
Michael  Nemtsev [.NET/C# MVP] :: blog: http://spaces.live.com/laflour 

"The greatest danger for most of us is not that our aim is too high and we
miss it, but that it is too low and we reach it" (c) Michelangelo

a> I am confused, I come from Win32 and am now trying to learn C#
a> threading
a>
a> I have a simple winform with a button, in the button's eventhandler I
a> create a thread, I want the thread to report progress to the form
a> i.e. writing a line in a list box, but the app throws an exception
a> complaining about the listbox being in another thread. Fine, but how
a> do solve this in the simplest manner?
a>
a> Here is some of the code:
a>
a> in the button event handler I start the thread
a> ...
a> Thread workerThread = new Thread(SimulatedClient);
a> workerThread.IsBackground = true;
a> workerThread.Name = "My Thread";
a> workerThread.Start(this);   // the form instance passed
a> as argument
a> ...
a> in the form I have a listbox say 'lbList'
a>
a> the thread function is declared as (not sure if using static is
a> needed here)
a>
a> private static void SimulatedClient(Object objParent)
a> {
a> MyFormClass mfc = (MyFormClass)objParent;  // getting the
a> form instance
a> ... do some stuff ...
a> mfc.Items.Add("Some Msg");   <-- gives the exception
a> }
a> All of the above is in the same form class.
a>
a> I have looked at delegates and events a bit but the coin hasn't
a> fallen down yet :) In Win32 I would for instance send a message from
a> the thread to the main window, how is this done in C#/.NET?
a>
a> Thanks in advance.
a> Anders.
ajk - 22 Feb 2008 08:59 GMT
Michael Nemtsev [ MVP ] wrote:
> Hello ajk,
>
[quoted text clipped - 3 lines]
> WBR,
> Michael  Nemtsev [.NET/C# MVP] :: blog: http://spaces.live.com/laflour

thanks as well, good article.

BR/Anders.
Mufaka - 22 Feb 2008 07:00 GMT
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

> I am confused, I come from Win32 and am now trying to learn C#
> threading
[quoted text clipped - 37 lines]
> Thanks in advance.
> Anders.
ajk - 22 Feb 2008 08:59 GMT
> You need to use BeginInvoke to marshal back to the ui thread.
>
[quoted text clipped - 58 lines]
> > Thanks in advance.
> > Anders.

Thank you, this was what I was looking for.

BR/Anders.
Nicholas Paldino [.NET/C# MVP] - 22 Feb 2008 13:27 GMT
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).

   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).

   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.

Signature

         - Nicholas Paldino [.NET/C# MVP]
         - mvp@spam.guard.caspershouse.com

> You need to use BeginInvoke to marshal back to the ui thread.
>
[quoted text clipped - 58 lines]
>> Thanks in advance.
>> Anders.
Richard Blewett - 22 Feb 2008 15:48 GMT
Hmmm, not sure if I agree with this Nicholas.

<inline>

----- Original Message -----
From: "Nicholas Paldino [.NET/C# MVP]" <mvp@spam.guard.caspershouse.com>
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

>> You need to use BeginInvoke to marshal back to the ui thread.
>>
[quoted text clipped - 58 lines]
>>> Thanks in advance.
>>> Anders.
Nicholas Paldino [.NET/C# MVP] - 22 Feb 2008 16:23 GMT
Richard,

   See inline:

> Hmmm, not sure if I agree with this Nicholas.
>
[quoted text clipped - 15 lines]
> confirmed by the winforms team some time ago (although exactly where
> escapes me for now)

   You are right here.  I haven't seen this before, but I'll acknowledge my
error here.  This is the thread that you are referring to:

http://discuss.develop.com/archives/wa.exe?A2=ind0311b&L=dotnet-clr&P=9244

>>    BeginInvoke will make the posting of the windows message which causes
>> the call in the UI thread asynchronous.  Execution will return
[quoted text clipped - 5 lines]
> 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.

   If the order of the UI updates is important, then you need to use
Invoke.  BeginInvoke can not guarantee the order that the messages will get
processed in.  If you have two successive calls to BeginInvoke one after
another, it can't be guaranteed that the first call to BeginInvoke will
necessarily process before the second call to BeginInvoke.  While it is
^most likely^ that will be the case when processing the successive calls, it
is not guaranteed.

   So depending on what your program is doing, and the information it is
displaying (and the order it displays it in), it might or might not be a
good idea.

Signature

         - Nicholas Paldino [.NET/C# MVP]
         - mvp@spam.guard.caspershouse.com

>>    Calling the Invoke method circumvents this, as it will wait until the
>> UI thread processes the delegate, and in this situation, is the better
[quoted text clipped - 77 lines]
>>>> Thanks in advance.
>>>> Anders.
Peter Duniho - 22 Feb 2008 07:02 GMT
> I am confused, I come from Win32 and am now trying to learn C#
> threading
[quoted text clipped - 4 lines]
> complaining about the listbox being in another thread. Fine, but how
> do solve this in the simplest manner?

http://search.msdn.microsoft.com/Default.aspx?brand=Msdn&refinement=00&locale=en
-us&lang=en-us&query=%22cross-thread%20operation%20not%20valid%22


Or

http://groups.google.com/groups/search?q=group%3Amicrosoft.public.dotnet.languag
es.csharp+cross-thread+operation&qt_s=Search


Or, for that matter...

Just click on the link in the debugger's exception alert that promises to  
take you to additional help.  Where it will explain what to do.

Pete

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.