вторник, 16 марта 2010 г.

C# iterators based scheduling

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.

воскресенье, 14 марта 2010 г.

C# 4.0 events. Small implementation change

C# 4.0 is going to change the way how event handlers addition and removal is implemented. From it birth C# compiler used to add special accessor methods to every event which didn’t have its own accessors declared. For thread safety those auto accessors had MethodImpl(MethodImplOptions.Synchronized) attribute defined on them. Using that attribute on publicly accesible methods is considered harmful because at runtime those methods are wrapped in lock(this) or lock(typeof([TypeDeclaringTheEvent])) for static events which, in its turn, is a bad practice as well.

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
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;

        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