6 ms·
Asynchrony in C# 5, Part One
- ghurlman 16y agoVisual Studio "Async" CTP freely downloadable: http://msdn.microsoft.com/en-us/vstudio/async.aspx http://msdn.microsoft.com/en-us/vstudio/async.aspx
- kevingadd 16y agoI 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).
- bad_user 16y agoThey have been freakishly coherent about building features on top of the old ones.
- dschobel 16y agoHere's hoping they fix closures in C# 5. (ref: http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closi... )
- trezor 16y agoI wouldn't go so far to say as there is anything wrong in closures itself, as much as a special case with regard to how it plays out in combination with the way the iterator pattern is integrated into the language itself. I agree that in the example provided it does seem counter-intuitive at first, but v is clearly a variable tied to the the loop and there is nothing that explicitly tells us if it is scoped outside the loop or to the code-block within the loop. If anything, I'd say it's the implementation of the iterator pattern which is broken, not the closures themselves (which I've had zero issues with).
- bad_user 16y agoClosures close over variables, not over values; the behavior in C# is correct in this regard.
- dschobel 16y agoI'm well aware of what the implementation is. If you read the reference, closing over variables is one of the most common source of customer complaints about a "bug" in the compiler as the implementation is completely counter-intuitive until you look at the MSIL. Ergo, they should fix closures.
- sid0 16y agoYeah, I've been bitten by this more than once while writing code using for-each and Iterator in JavaScript. It is definitely counter-intuitive.
- bad_user 16y agoWhat people that get bitten don't get: closures are lazy. They aren't executed right away unless you want to. That's their purpose, with the most common use-case being to postpone a piece of computation for later (until you've got everything you need). So it cannot close over values, and if it did it would mean that you couldn't modify the values from the outer-scope (which you just closed over) ... making closures totally useless.
- deleted 16y ago[deleted]
- fleitz 16y agoIf 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 }
- dinkumthinkum 16y agoWhy not just write it in C#.
- fleitz 16y agoBecause in F# you can write that code today rather than in a year or two when C# 5.0 is released. Also, the pattern used by F# to do this sort of thing is exposed to the user so you can create any kind of monad instead of just one for async. In F# this behavior is integral to the language and not just syntactic sugar for a couple 'special' cases. So instead of learning one syntax for continuations and another for async, sql, etc, etc. You just have one system to learn that can be applied to many different problems, and you don't have to wait for Anders to bless your problem as important enough to have syntactic sugar added. The other thing to note is that there will be many 'special cases' about using this code that don't work with typical C# code because of its mutability. It's similar to all the weirdness around using the yield statement. Like how you can't have an out parameter on a method that uses a yield statement and some weirdness around exceptions.
- barrkel 16y agoInternally, the new mechanism (currently) uses a method called 'MoveNext' to advance the continuation state machine; it may be leveraging existing iterator conversion support.
- ecoffey 16y agoI 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.
- kenjackson 16y agoThis 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 16y agoSeriously. 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 16y agoMaybe you'll find stratified js -- http://stratifiedjs.org/ 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 16y agoI'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.
- statictype 16y agoIf 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.
- nathanwdavis 16y agowow, this looks very much inspired by F#'s async expressions. I'm really looking forward to being able to use this.
- itsnotvalid 16y agoThe designers of C# 100.0 realized that writing code is painful, so they added super AI to solve the problem for you.