Venkat: I would go to the link to Chris Sells' site and read all the
articles he aggregated.

Regards, 
J. Vince Pacella / OOCL Chicago 
Cell 773-454-8683 Fax - 773-867-5050 

Cargo Tracking Online at: 
www.cargosmart.com 

 

> -----Original Message-----
> From: Unmoderated discussion of advanced .NET topics. 
> [mailto:[EMAIL PROTECTED] On Behalf Of 
> Sathiamurthy, Venkat
> Sent: Monday, February 28, 2005 9:02
> To: [email protected]
> Subject: Re: [ADVANCED-DOTNET] Asynchronous call - Thread life
> 
> My many Thanks to Ian Griffiths and Bob Lynch, Your comments 
> and suggestions were very helpful.
> 
> Can you please explain me or refer article about 
> Control.Invoke/Control.BeginInvoke and give me more insights 
> about - When Control.InvokeRequired = true, calling 
> this.BeginInvoke(new
> methoddelgate(function)) will call the control's properties 
> using correct thread?
> 
> Thanks,
> Venkat
> 
> -----Original Message-----
> From: Unmoderated discussion of advanced .NET topics.
> [mailto:[EMAIL PROTECTED] On Behalf Of Ian 
> Griffiths
> Sent: Thursday, February 24, 2005 6:19 AM
> To: [email protected]
> Subject: Re: [ADVANCED-DOTNET] Asynchronous call - Thread life
> 
> 
> First of all, a handy tip - it looks like you pasted the code 
> directly from VS.NET into your mail client.  For some reason, 
> when sending mail as plain text (and I *think* these 
> listservs are set up always to send as plain text) code 
> always comes out looking wrong when you do this - it gets 
> double spaced and loses all its tabs, making it really hard 
> for anyone to read the code.  (This in turn makes it hard for 
> them to help
> you.)  So I always copy from VS.NET and past into Notepad, 
> and then recopy from Notepad and paste into the email client. 
> 
> But now on to your actual questions:
> 
> > I have a situation, I am calling a method asynchronously, 
> which does 
> > not return values. If I make 100 call asynchronously, will the 
> > performance go down?
> 
> Define 'performance' in this context.  There isn't really a 
> simple answer to your question, but I can explain a little 
> about what actually happens when you do this, which I hope 
> will enable you to work out what the answer will be in your 
> particular situation.
> 
> First, when you say you are calling a method asynchronously, 
> do you mean you're using asynchronous delegate invocation?  
> Or one of the many other forms of asynchrony supported in the 
> .NET Framework?  (E.g.
> Control.BeginInvoke - that is implemented in a completely 
> different fashion from the BeginInvoke method supplied by all 
> delegates.)
> 
> Looking through the code you posted, the only place I see any async is
> here:
> 
>     private void Form2_Load(object sender, System.EventArgs e)
>     {
>         mydelegate dl=new mydelegate(Form2_EventSubscribe);
>         dl.BeginInvoke(null,null);
>     }
> 
> So that would be asynchronous delegate invocation then.
> 
> In which case, here's what will happen when you make 100 
> calls.  Each time you call BeginInvoke on a delegate, the 
> delegate queues up a work item with the CLR thread pool.  The 
> thread pool has a work queue associated with it, and the 
> threads in the pool all retrieve items from this queue and 
> work on them.
> 
> So the first thing that will happen when you put 100 items in 
> the queue in quick succession is that the thread pool queue 
> length will grow. This in itself is not going to have a major 
> impact on performance - it just takes up some memory.  
> (Although there will eventually come a point where the thread 
> pool will refuse to accept new work items.)
> 
> What happens next depends on three things: 1) how long each 
> work item takes to execute, 2) what proportion of the time 
> those work items spend using CPU cycles vs. waiting for 
> something to happen, and 3) how many CPUs you have.
> 
> If each item executes very quickly, then what will most 
> likely happen is that the thread pool will use the same 
> thread to execute each item in turn - so you might never see 
> more than 1 thread pool thread being used.
> But if they take longer (e.g. a couple of seconds) the thread 
> pool will consider changing its strategy.  It might increase 
> the number of threads, although it will only do so if the 
> threads are not CPU-bound.
> If the CPU is 100% busy, it won't bother creating extra 
> threads.  If the CPU seems to have significant idle time, 
> it'll create more threads.  But it will never create more 
> threads than 25*(number of CPUs in system) unless you've 
> taken steps to change from the default settings for the threadpool.
> 
> What impact will this have on performance?  Well, the single 
> most important factor will be the work you're doing 
> asynchronously, which is why it's not possible to say, in 
> general, what the impact of putting 100 work items in the 
> queue will be - it depends on the work in question.
> 
> If the work you're doing is expensive, then obviously it'll 
> slow things down.  In the worst case, if all of these threads 
> are performing IO intensive work on the same device, you 
> might get 25 threads all simultaneously trying to use that 
> device.  (Or 50 threads on a dual proc, etc...)  But you 
> won't see the system attempt to run all 100 items at once.  
> (Unless you have a 4 CPU box...)
> 
> Since the performance characteristics are heavily determined 
> by what you're actually doing on those threads, the only way 
> to know for sure is to try it out and see what happens.
> 
> 
> > My understanding is - I can't use threadpool,
> 
> Actually you *are* using the threadpool.  Calling BeginInvoke 
> on a delegate implicitly uses the threadpool.  (Although 
> there are serious problems with your code, as I'll explain 
> later.  You shouldn't be using the thread pool.  But you 
> shouldn't be creating other threads either.
> The bulk of the code you're trying to run asynchronously will 
> in fact have to run on the UI thread...  But that's just 
> because of what you're trying to do in the method you're 
> calling asynchronously.)
> 
> 
> 
> > because FormA  loads FormB and which inturn calls a method 
> > Asynchronously. FormA may load 100 FormB, but FormB will call the 
> > method only once per instance.
> 
> Why would that stop you using the threadpool?
> 
> First of all, bear in mind that with the code you posted, Form1 and
> Form2 will both use the same UI thread.  Form1 creates instances of
> Form2 here:
> 
>     private void button1_Click(object sender, System.EventArgs e)
>     {
>         Form2 frm2 = new Form2 ();
>         frm2.Show ();
>     }
> 
> That's a click handler, which will always run on the UI 
> thread of Form1.
> So you're creating instances of Form2 on Form1's UI thread.
> 
> So all 100 instances of Form2 will run on the same thread in 
> your program.  This is normal, and does not stop you from 
> using the thread pool for async work.
> 
> 
> 
> > a. I don't have a need to call endinvoke, What will happen to that 
> > child thread, when it will die?
> 
> First of all you MUST call EndInvoke.  It is simply not 
> correct to say that you "don't have a need to call 
> endinvoke."  If you call BeginInvoke on a delegate you are 
> *required* to call EndInvoke on it at some point.
> So you do have a need - the need to call EndInvoke is a 
> direct consequence of calling BeginInvoke.
> 
> As for the second half of your question, I think you've 
> misunderstood how asynchronous delegate invocation works.  In 
> this part of your code:
> 
>     mydelegate dl=new mydelegate(Form2_EventSubscribe);
>     dl.BeginInvoke(null,null);
> 
> this does not cause a thread to be created.  It just queues 
> up work with the thread pool.  This work will be handled by 
> one of the threads in the thread pool, a thread which will 
> then go on to do other things.  (That's the whole point of a 
> thread pool.)  So the system doesn't create a thread 
> specially to deal with this BeginInvoke call.  (In certain 
> circumstances, calling BeginInvoke can trigger the creation 
> of a new thread in the thread pool.  But that thread will 
> always outlive the work that caused it to be created, and 
> will usually go on to handle further work items.  So in 
> short, there is not a 1 to 1 correspondance between threads 
> and calls to BeginInvoke.)
> 
> So, when will the thread that executed your async call die?  
> Whenever the thread pool decides it is time for that thread 
> to die.  This could happen at any time - it might happen 
> straight away, it might not happen until the program exits.  
> But since you don't own that thread, it's not really useful 
> for you to know when it exits.  Thread pool threads are not 
> yours, they are merely loaned to you.  If you're doing 
> anything that requires you to know when the thread dies, you 
> probably shouldn't be using the thread pool.
> 
> 
> 
> > b. How do I control the child thread, i.e. terminate the 
> child thread 
> > created my the asycn call?
> 
> See above - you can't, and there was no thread created just 
> for your async call.  The thread is owned by the thread pool, 
> and is likely to service many async requests in its lifetime.
> 
> If you have some need to manage the lifetime of the thread, 
> you can't use the threadpool.  Which means you can't use 
> asynchronous delegate invocation.  Create your own thread instead.
> 
> 
> 
> By the way, your code as posted is horribly broken, and you 
> should never write code that works like this.  The problem is 
> that the method you are launching asynchronously attempts to 
> do things with the UI.  For example, it contains code like this:
> 
>     this.button1.Click += new System.EventHandler(this.button1_Click);
>     this.button2.Click += new System.EventHandler(this.button2_Click);
>     this.MouseDown += new
>         System.Windows.Forms.MouseEventHandler(this.Form2_MouseDown);
> 
> This violates the golden rule of multithreading in Windows 
> Forms: you must not use controls on any thread other than the 
> thread on which they were created.  This code snippet breaks 
> that rule on every line - you're not allowed to subscribe to 
> a control's events from any thread other than the UI thread.
> 
> The documentation for the Control class makes it pretty clear 
> that your code isn't right - look at what it says under 
> "Thread Safety":
> 
> " Only the following members are safe for multithreaded operations:
> BeginInvoke, EndInvoke, Invoke, InvokeRequired, and CreateGraphics."
> 
> Those are the only exceptions to the golden rule.  Note that 
> it does not say that members such as Click or MouseDown are 
> safe for multithreaded operations.  So the only thread you 
> can ever run code like this on is the UI thread.  (And by the 
> way, it makes no difference whether you use the thread pool 
> or you create your own threads.  It's all against the rules 
> because you have to use the UI thread.)
> 
> What's less immediately obvious from the docs is that 
> controls have thread affinity, i.e. it's not enough to do use 
> locking primitives to serialize access to them - you must use 
> the same thread every time.
> (This is made clear in the documentation for 
> Control.InvokeRequired.  It would be nice if it were also 
> made explicit in Thread Safety section of the main page for Control.)
> 
> For more information on how to write multithreaded code there 
> are a number of articles you can look at (including one by me 
> :) ) - Chris Sells has compiled a list here:
> 
>  http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=1707
> 
> 
> 
> 
> --
> Ian Griffiths - DevelopMentor http://www.interact-sw.co.uk/iangblog/
> 
> > -----Original Message-----
> > From: Sathiamurthy, Venkat
> > 
> > I have a situation, I am calling a method asynchronously, which does
> not
> > return values. If I make 100 call asynchronously, will the 
> performance
> 
> > go down?
> > 
> > My understanding is - I can't use threadpool, because FormA  loads
> FormB
> > and which inturn calls a method Asynchronously. FormA may load 100 
> > FormB, but FormB will call the method only once per instance.
> > 
> > My additional questions are,
> > a. I don't have a need to call endinvoke, What will happen to that
> child
> > thread, when it will die?
> > b. How do I control the child thread, i.e. terminate the 
> child thread 
> > created my the asycn call?
> 
> ===================================
> This list is hosted by DevelopMentor(r)  http://www.develop.com
> 
> View archives and manage your subscription(s) at 
> http://discuss.develop.com
> 
> ===================================
> This list is hosted by DevelopMentor(r)  http://www.develop.com
> 
> View archives and manage your subscription(s) at 
> http://discuss.develop.com
> 
> 
> 


IMPORTANT NOTICE
Email from OOCL is confidential and may be legally privileged.  If it is not 
intended for you, please delete it immediately unread.  The internet cannot 
guarantee that this communication is free of viruses, interception or 
interference and anyone who communicates with us by email is taken to accept 
the risks in so doing.  Without limitation, OOCL and its affiliates accept no 
liability whatsoever and howsoever arising in connection with the use of this 
email.  Under no circumstances shall this email constitute a binding agreement 
to carry or for provision of carriage services by OOCL, which is subject to the 
availability of carrier's equipment and vessels and the terms and conditions of 
OOCL's standard bill of lading which is also available at http://www.oocl.com.

===================================
This list is hosted by DevelopMentor�  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to