Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous methods and asynchronous delegates

C# 3.0 in a nutshell says asynchronous methods and asynchronous delegates looks similar but the behavior is very different.

Here is what the book says about both.

Asynchronous methods

  1. Rarely or never blocks any thread.
  2. Begin method may not immediately return to the caller.
  3. An agreed protocol with no C# language support.

Asynchronous delegates

  1. May block for any length of time
  2. BeginInvoke return immediately to the caller.
  3. Built-in compiler support.

The book also says, The purpose of asynchronous methods is to allow many tasks to run on few threads; the purpose of asynchronous delegates is to execute a task in parallel with the caller.

When I looked into the BeginRead() method in System.IO.Stream class through reflector, it is using a delegate and calling BeginInvoke on that. So an asynchronous method is using an asynchronous delegate internally.

  1. In such case, how can one say their behaviors are different? Since it uses delegates internally, how a comparison like the above is possible?
  2. Do you think working with a delegate's BeginXXX method is the way to execute a function in parallel to the caller?
  3. What is the proper way to implement asynchronous methods by maintaining all the advantages like making good use of CPU?

Any thoughts?

like image 916
Navaneeth K N Avatar asked Sep 13 '09 17:09

Navaneeth K N


People also ask

What are asynchronous delegates?

An asynchronous delegate is a delegate that you call, and it returns a Task of some kind. It's not the call that's asynchronous - it's the processing within the delegate.

What are async methods?

An async method runs synchronously until it reaches its first await expression, at which point the method is suspended until the awaited task is complete. In the meantime, control returns to the caller of the method, as the example in the next section shows.

How do you call asynchronous delegates?

Delegates enable you to call a synchronous method in an asynchronous manner. When you call a delegate synchronously, the Invoke method calls the target method directly on the current thread. If the BeginInvoke method is called, the common language runtime (CLR) queues the request and returns immediately to the caller.

What is synchronous and asynchronous methods in C#?

Synchronization means two or more operations happen sequentially. Asynchronous means two or more operations are running in different contexts (thread) so that they can run concurrently and do not block each other.


2 Answers

At the core, there are two main behaviors you may see when you call BeginFoo() with a callback.

  1. Work is started on a background thread, and that thread will be used the entire time up until the work is completed and the callback is invoked (e.g. because the work is synchronous).
  2. Though some work happens on a background thread, the thread need not be in use the entire time (e.g. because the work involves System IO which can schedule callbacks on e.g. the IOCompletionPort).

When you use a delegate, behavior #1 above happens.

Some APIs (that have underlying support for non-blocking IO calls) support behavior #2.

In the specific case of 'Stream', I am not sure, but my guess is it is an abstract base class and so this is merely the default behavior for a subclass that implements only a synchronous version of Read. A 'good' subclass would override BeginRead/EndRead to have a non-blocking implementation.

The advantage of #2, as you said, is that you can have e.g. 100 pending IO calls without consuming 100 threads (threads are expensive).

like image 157
Brian Avatar answered Oct 06 '22 21:10

Brian


  1. The implementation can be different; for example, an async IO call may choose to make use of completion ports to minimise the cost to the system while not doing anything.
  2. It is certainly a way; you could also use BackgroundWorker, ThreadPool.QueueUserWorkItem, or Parallel.For (etc) in .NET 4.0
  3. Varies per implementation

I think what the book is trying to highlight is that delegates always include this pattern:

  • a synchronous call (Invoke) that can block
  • an async call (BeginInvoke) that shouldn't really block unless the thread-pool is saturated

but it isn't the only pattern. Also; more recently (for example, the async IO methods in Silverlight, or in WebClient): rather than an IAsyncResult, an event is used to signal completion.

like image 24
Marc Gravell Avatar answered Oct 06 '22 22:10

Marc Gravell