If you ask Google about asynchronous iterators you'll see that a lot of people have been using C# iterators for doing things that iterators were not supposed to do in the first place - from effective and convinient IO to microthreading and cooperative multitasking.
Several months ago being influenced by CCR iterators and AsyncEnumerator I tried to create microthreading library that could schedule microthreads on many OS threads and be integrated with different async patterns - from APM through EAP to TPL's Tasks. The early prototype looked promising but iterators are really optimzed for generating sequences effectively so there are some restrictions and inconveniences.
I hope the implementation of resumable methods that may appear in future C# will let us build on top of it all aforementioned scenarios, and even those which the future methods are not supposed to be used for.
Why iterators were implemented the way they were implemented in Eric Clipperts' serie on iterator blocks.
вторник, 16 марта 2010 г.
C# iterators based scheduling
воскресенье, 14 марта 2010 г.
C# 4.0 events. Small implementation change
In C# 4.0 event accessors don't use explicit locking, but implement what can be considered as optimistic locking. Look at the following:
//pre 4.0 [MethodImpl(MethodImplOptions.Synchronized)] public void add_Disposed(EventHandler value) { this.Disposed = (EventHandler) Delegate.Combine(this.Disposed, value); } // 4.0 public void add_Disposed(EventHandler value) { EventHandler handler2; EventHandler disposed = this.Disposed; do { handler2 = disposed; EventHandler handler3 = (EventHandler) Delegate.Combine(handler2, value); disposed = Interlocked.CompareExchange(ref this.Disposed, handler3, handler2); } while (disposed!= handler2); }
With the new algorithm we don't have to have one private object for each public event just to protect them from lockin issues. Besides that it is a little bit lighter and more performant. Delegate type itself hasn't changed at all. Delegates have been immutable reference types from the very begining. The only question I have: Why they didn't do that in the first place!?
More details in C# compiler team member's blog:
Field-like Events Considered Harmful
Events get a little overhaul in C# 4, Part II: Semantic Changes and +=/-=
воскресенье, 7 марта 2010 г.
What I’d like to see in C# 5.0
Axum, an experimental language, has such a feature as async methods. In such methods interaction with interaction points and APM based API happens asynchronously.
Besides that there are signs that in the future C# will support resumable methods. Luca Bolognese opened up some details at the PDC 2009 session Future of C# and VB. Fast-forward to 50:00 where he shows experimental yield keyword in the method returning Async<T>.
That’s great news because with what we have now if you want to make long running call not keeping your thread waiting/doing nothing/consuming memory you have to put all your logic in callback methods calling each other. With resumable methods such code would be much easier to write, read and refactor, and the exception handling would look like synchronous, stack based.
But being excited about the feature:
- I don’t like the idea of introducing a new type (Async<T>) when we already have Task and Task<T> types
- I’d like C# to recognize not only APM pattern based API but methods and properties that return Task or Task<T> as well. If you compare Task and IAsyncResult you’ll see that a Task based asynchronous API is much simpler, cleaner and easier to implement. Compare the next two variations:
//Task based API
public Task UploadData(string uri, string data) { … }
public Task<string> DownloadData(string uri) { … }
public Task<int> TotalNumberOfRows { get { … } }
//APM based API
public IAsyncResult BeginUploadData(string uri, string data, AsyncCallback callback, object context) { … }
public void EndUploadData(IAsyncResult ar)
public IAsyncResult BeginDownloadData(string uri, AsyncCallback callback, object context) { … }
public string EndDownloadData(IAsyncResult ar)
public IAsyncResult BeginGetTotalNumberOfRows(AsyncCallback callback, object context) { … }
public int EndGetTotalNumberOfRows(IAsyncResult ar)
- I’d like C# to recognize extension methods that implement APM or Task based API