Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between delegate.BeginInvoke and using ThreadPool threads in C#

In C# is there any difference between using a delegate to do some work asynchronously (calling BeginInvoke()) and using a ThreadPool thread as shown below

public void asynchronousWork(object num)     {         //asynchronous work to be done         Console.WriteLine(num);     }   public void test()     {         Action<object> myCustomDelegate = this.asynchronousWork;         int x = 7;          //Using Delegate         myCustomDelegate.BeginInvoke(7, null, null);          //Using Threadpool         ThreadPool.QueueUserWorkItem(new WaitCallback(asynchronousWork), 7);         Thread.Sleep(2000);     } 

Edit:
BeginInvoke makes sure that a thread from the thread pool is used to execute the asynchronous code , so is there any difference?

like image 980
nighthawk457 Avatar asked Apr 26 '12 20:04

nighthawk457


People also ask

What is difference between Invoke and BeginInvoke?

Invoke : Executes on the UI thread, but calling thread waits for completion before continuing. Control. BeginInvoke : Executes on the UI thread, and calling thread doesn't wait for completion.

When should you not use Threadpool?

Thread pools do not make sense when you need thread which perform entirely dissimilar and unrelated actions, which cannot be considered "jobs"; e.g., One thread for GUI event handling, another for backend processing. Thread pools also don't make sense when processing forms a pipeline.

Why use delegates?

Delegates allow methods to be passed as parameters. Delegates can be used to define callback methods. Delegates can be chained together; for example, multiple methods can be called on a single event. Methods don't have to match the delegate type exactly.

What is BeginInvoke?

BeginInvoke(Action) Executes the specified delegate asynchronously on the thread that the control's underlying handle was created on. BeginInvoke(Delegate) Executes the specified delegate asynchronously on the thread that the control's underlying handle was created on.


1 Answers

Joe Duffy, in his Concurrent Programming on Windows book (page 418), says this about Delegate.BeginInvoke:

All delegate types, by convention offer a BeginInvoke and EndInvoke method alongside the ordinary synchronous Invoke method. While this is a nice programming model feature, you should stay away from them wherever possible. The implementation uses remoting infrastructure which imposes a sizable overhead to asynchronous invocation. Queue work to the thread pool directly is often a better approach, though that means you have to co-ordinate the rendezvous logic yourself.

EDIT: I created the following simple test of the relative overheads:

int counter = 0; int iterations = 1000000; Action d = () => { Interlocked.Increment(ref counter); };  var stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); for (int i = 0; i < iterations; i++) {     var asyncResult = d.BeginInvoke(null, null); }  do { } while(counter < iterations); stopwatch.Stop();  Console.WriteLine("Took {0}ms", stopwatch.ElapsedMilliseconds); Console.ReadLine(); 

On my machine the above test runs in around 20 seconds. Replacing the BeginInvoke call with

System.Threading.ThreadPool.QueueUserWorkItem(state => {     Interlocked.Increment(ref counter); }); 

changes the running time to 864ms.

like image 86
Lee Avatar answered Sep 27 '22 22:09

Lee