
Asynchrony in C# 5, Part One - pauldino
http://blogs.msdn.com/b/ericlippert/archive/2010/10/28/asynchrony-in-c-5-part-one.aspx
======
kevingadd
I cannot express how thrilled I am to see Microsoft address this problem in
their language, and to see them do it in such a well thought-out way.

In particular, I was kind of underwhelmed by the Task stuff they added in 4.0,
because what I was expecting was something like this new await/async syntax -
so now, seeing that they used the (comparatively primitive) Task
infrastructure in order to build await/async, I feel bad for doubting them. So
far on a cursory examination, these new features solve almost all my
concurrency problems (at least, from the perspective of a compiler), and
should let me throw out a ton of existing code that I've been maintaining. I
basically wrote my own cooperative scheduler and infrastructure to do exactly
this on top of the iterator features from C#2/3, and it's been a godsend, so
it's going to be nice to have it in the compiler :)

In particular I'm pleased that instead of dictating that everyone use only
cooperative threading or preemptive threading for concurrency, they're
exposing both scheduling techniques with easy-to-use APIs that integrate well
with each other. To me, this seems like a much better approach than picking a
One True Concurrency Mechanism (like, for example, node did).

~~~
fleitz
If you want to write async code in .NET, use F#.

You can compose and BeginOp EndOp functions into a function that returns an
Async<T>

I've probably screwed up the exact function name but here's the psuedo code.

Example: Imagine a C# class as follows

    
    
      public class Foo {
         public AsnycResult BeginGetBar(int bar_id) { // something }
         public Bar EndGetBar(AsnycResult result) {
            // something
            return bar;
         }
      }
    

Now to consume in F# create an extension method

    
    
      type Foo with
       member x.AsyncGetBar = Async.FromAsyncResult(x.BeginGetBar, x.EndGetBar)
    

Now to use it

    
    
      let somefunc = async {
                      let x = new Foo();
                      let! bar =  x.AsyncGetBar(10);
                      // do something with bar
                   }
    

What F# does is create a call back that is the rest of the function after the
let!/do! statement, basically your code is split into a call back everytime
you use a let!/do! binding.

For a more interesting example lets say you want an async file copy.

    
    
      let copy s1:Stream s2:Stream = 
       let buffer:byte[] = Array.init 8192
       let rec copy = async {
         let! read = s1.AsyncRead(0,buffer.Length,buffer)
         match read with 
         | 0 -> ()
         | x -> do! s2.AsyncWrite
                return! copy()   
       }
    

The nice part about this is that copy is a fully reusable piece of code async
code. So anytime you're in an async block and need to copy a file, so...

    
    
      let move s1 s2 = async {
        do! copy s1 s2
        do! delete s1
      }

~~~
jules
With this new extension to the C# language you can do the same in C#, it's the
whole point of this extension. Actually the C# way of doing it seems to be a
bit nicer than F# even.

~~~
bad_user
"async" in F# is based on monad comprehensions, making it a feature you
could've come up yourself.

Personally I don't like magic keywords baked in the compiler.

~~~
trezor
Even though I never fully got the hang of F#, I must agree on this one. I like
C# as a language, but too many magic keywords just starts smelling wrong.

Having a compiler do work for you and simplify your code is nice and you wont
see me complain about this feature in particular.

On the other hand, I've made enough monadic extension classes (NullSafety,
Object-transactions, etc) and extension methods to cover up for short-comings
as I've seen them in my projects, and it always bugs me how this effectively
forces me to clutter up my syntax.

Consider the following code

    
    
       var x = GetSomeObject()  // can be null
               .SubProperty     // can also be null
               .Indexer[index]; // can also be null
    

This code can cause NullReferenceExceptions all over, so to do it safely, you
need to add a bunch of if (object == null) checks.

With my NullSafe-extensions, the expression looks like this:

    
    
       var x = GetSomeObject().AsNullSafe() 
               .Do((x) => x.SubProperty)    
               .Do((x) => x.Indexer[index])
               .Value; // can be null or default
    

Within the C# type-system, there is no way to get around this clutter and
massive use of lambdas. Granted, it looks better than the corresponding code
with manual null-checks for every step, but with lambda expression comes the
cost of not being able to debug & correct code at runtime.

~~~
barrkel
Magic keywords, as you put them, on the other hand increase the ability of the
language to be tooled. You get better debugging, code completion, diagnostics
etc. when what could be a library feature is implemented as a first-class
language feature.

The other side of the coin is that many larger businesses use coding standards
to restrict the idioms in use across the enterprise. When the language is
flexible enough to freely create new idioms (like Lisp and Smalltalk in
extremis - the notion of DSLs came from these for good reasons), many folks
fear that every codebase in the company will become its own silo of idioms,
increasing the ramp-up time of new developers coming in. When an idiom comes
packaged up from the tool vendor, "in the box" as it were, however, they can
(hopefully) rely on new devs coming in to be up to speed already; as well as
fairly confident it's been thought through properly.

Furthermore, third-party libraries and software component vendors in general
benefit by being able to assume that everyone knows and can support the
idioms.

------
statictype
If people doubt that Microsoft still has smart hackers working there, you just
need to follow Eric Lippert's blog. Even if you have no interest in C#, he has
a lot of genuinely interesting thoughts on programming and related topics.

------
ghurlman
Visual Studio "Async" CTP freely downloadable:

<http://msdn.microsoft.com/en-us/vstudio/async.aspx>

------
kenjackson
This is probably the best language feature I've seen since generics in C#.
Actually, I think it may just simply be the best language feature in C#,
period. I wish I could use it in shipping code right now.

~~~
statictype
Seriously. I've wanted something like this in javascript for ages. Given the
complete async nature of modern javascript, it would be a huge win. On the
other hand, async code in javascript (as it is now) does look cleaner than the
equivalent on C#.

~~~
alex_muscar
Maybe you'll find stratified js -- <http://stratifiedjs.org/> \-- interesting.
I haven't tried it myself, but it seems to fit the bill. As a side note: IMHO
C#'s use of only 2 keywords and method combinators is cleaner than stratified
js' approach.

------
MichaelGG
I'm not that thrilled with yet more specific syntax for one feature. F#'s
approach of having a simple core that can be extended in-language (versus only
via the compiler with new syntax) seems like a much more elegant approach.

But it's nice that async code in C# won't be as painful as it is today.

------
ecoffey
I really like that Eric Lippert dropped this little nugget on us as the end of
a long and nerdy blog series :-)

I would love to shadow that compiler team for a week or two, and get to sit in
on some of those discussions.

------
nathanwdavis
wow, this looks very much inspired by F#'s async expressions. I'm really
looking forward to being able to use this.

------
itsnotvalid
The designers of C# 100.0 realized that writing code is painful, so they added
super AI to solve the problem for you.

