Friday, January 21, 2011

Async CTP on WP7

In this post I will show you how to use Async CTP released during last PDC conference inside your Windows Phone application. Async CTP extends two .Net platform languages C# and VB giving us a new way of writing asynchronous code. There are two main aspects of this project: new C#/VB compiler (two new keywords: async, await) and library AsyncCtpLibrary.dll. When the compiler sees asynchronous method it generates IL code (which we will see in details further) and that code is using some types from the mentioned library. The problem is that so far we have only two versions of library: .Net and Silverlight. So in this post I will show you how we can use  Async CTP on Windows Phone 7 despite these limitations.

The first thing we need to do before we write our first asynchronous method in the WP7 project is we need to add the reference to Silverlight version of the library AsyncCtpLibrary_Silverlight.dll. Just after doing it Visual Studio shows  a warning: “Adding a reference to a Silverlight assembly may lead to unexpected application behavior. Do you want to continue?”. The problem is that the assembly is compiled under full version of Silverlight and the Windows Phone does not contain the full version but some subset of it running on the top of .Net compact framework. So if we execute some code from such a assembly which is using types that are not available on the phone we will get the runtime exception. The key element of the AsyncCtpLibrary are Tasks and unfortunately they are not running on the phone throwing exception at runtime. The question is: can we use Async CTP without Tasks ? Of course we can! The whole mechanism behind asynchronous methods doesn’t force us to use the instance of type Task followed by await keyword. That type needs to contain method (instance or extension method) called GetAwaiter returning any type that contains appropriate pair of methods (instance or extension) BeginAwait and EndAwait. And all I did is I implemented such a matching type.

public enum AwaiterResultType
{
    Completed,
    Failed,
    Cancelled
}

public class AwaiterResult<T>
{
    public AwaiterResultType ResultType { get; private set; }
    public Exception Exception { get; private set; }
    public T Value { get; private set; }

    private AwaiterResult() { }
    public static AwaiterResult<T> Completed(T result)
    {
        return new AwaiterResult<T> { ResultType = AwaiterResultType.Completed, Value = result };
    }
    public static AwaiterResult<T> Failed(Exception exception)
    {
        return new AwaiterResult<T> { ResultType = AwaiterResultType.Failed, Exception = exception };
    }
    public static AwaiterResult<T> Cancelled()
    {
        return new AwaiterResult<T> { ResultType = AwaiterResultType.Cancelled };
    }
}

public class Awaiter<T>
{
    private SynchronizationContext Context { get; set; }
    private bool IsSynchronized { get; set; }
    private Action _continuation;

    public AwaiterResult<T> Result { get; private set; }

    private Awaiter() { }

    public Awaiter<T> GetAwaiter()
    {
        return this;
    }

    public bool BeginAwait(Action continuation)
    {
        if (Result != null)
            return false;

        _continuation += continuation;
        return true;
    }

    public T EndAwait()
    {
        if (Result == null)
            throw new InvalidOperationException("Awaiter does not contain the result yet.");

        if (Result.ResultType == AwaiterResultType.Completed)
            return Result.Value;

        if (Result.ResultType == AwaiterResultType.Failed)
            throw Result.Exception;

        return default(T); // if cancelled
    }

    private void OnResult(AwaiterResult<T> result)
    {
        if (result == null) throw new ArgumentNullException("result");
        if (Result != null) throw new InvalidOperationException("The result can be provided only once.");

        Result = result;
        if (IsSynchronized && Context != null)
        {
            Context.Post(o =>
                             {
                                 if (_continuation != null)
                                     _continuation();
                                 _continuation = null;
                             }, null);
            Context = null;
        }
        else
        {
            if (_continuation != null)
                _continuation();
            _continuation = null;
        }
    }

    public static Awaiter<T> Create(Action<Action<AwaiterResult<T>>> resultProvider, bool synchronizeWithCurrentContext = true)
    {
        if (resultProvider == null) throw new ArgumentNullException("resultProvider");

        var awaiter = new Awaiter<T> { IsSynchronized = synchronizeWithCurrentContext };
        if (synchronizeWithCurrentContext)
            awaiter.Context = SynchronizationContext.Current;
        resultProvider(awaiter.OnResult);
        return awaiter;
    }
}

The key class here is Awaiter class containing appropriate three methods: GetAwaiter, BeginAwait and EndAwait. This is an abstraction of asynchronous work (very similar to Task type) which at some point in time is finishing its work in one of three possible states: an exception could be thrown, maybe someone cancelled the execution or the work has been completed correctly returning some result. The constructor is private so the factory method called Create is the only way to create an instance of Awaiter type. So let’s see how we can use it:

public static class AwaiterEx
{
    public static Awaiter<T> Run<T>(Func<T> action)
    {
        return Awaiter<T>.Create(resultProvider =>
        {
            ThreadPool.QueueUserWorkItem(o =>
            {
                try
                {
                    var result = action();
                    resultProvider(AwaiterResult<T>.Completed(result));
                }
                catch (Exception exception)
                {
                    resultProvider(AwaiterResult<T>.Failed(exception));
                }
            },null);
        });         
    }

    public static Awaiter<object> Delay(TimeSpan timeSpan)
    {
        return Awaiter<object>.Create(resultProvider =>
        {
            var timer = new Timer(o => resultProvider(AwaiterResult<object>.Completed(null)));
            timer.Change((int)timeSpan.TotalMilliseconds, -1);
        });
    }
}

async private static void Sample()
{
    int intResult = await AwaiterEx.Run(() =>
    {
        Thread.Sleep(3000);
        return 123;
    });
    MessageBox.Show("Completed: " + intResult);

    await AwaiterEx.Delay(TimeSpan.FromSeconds(3));
    MessageBox.Show("After 3 seconds...");
}

Now let’s look at simplified version of what compiler is generating underneath to allow us to write synchronously looking code running asynchronously.

private static void SampleInternals()
{
    Awaiter<int> awaiter1 = null;
    Awaiter<object> awaiter2 = null;
    int state = 0;
    
    Action action = null;
    action = () =>
    {
        if (state == 1) goto JUMP_LABEL_1;
        if (state == 2) goto JUMP_LABEL_2;
        
        awaiter1 = AwaiterEx.Run(() =>
        {
            Thread.Sleep(3000);
            return 123;
        }).GetAwaiter();
        state = 1;
        
        if (awaiter1.BeginAwait(action))
            return;
        
        JUMP_LABEL_1:
        var intResult = awaiter1.EndAwait();
        MessageBox.Show("Completed: " + intResult);


        awaiter2 = AwaiterEx.Delay(TimeSpan.FromSeconds(3)).GetAwaiter();
        state = 2;

        if (awaiter2.BeginAwait(action))
            return;

        JUMP_LABEL_2:
        awaiter2.EndAwait();
        
        MessageBox.Show("After 3 seconds...");
    };

    action();         
}

The last thing worth mentioning is how to write asynchronous method returning some value. Asynchronous methods have two limitations: void, Task and Task<T> are the only valid return types and out parameters are not allowed. As we said before Tasks under WP7 don’t work so we cannot return Task object. In fact the solution is very simple:

public static class AwaiterEx
{
    public static Awaiter<object> BeginWriteAwaiter(this Stream stream, byte[] buffer, int offset, int numBytes)
    {
        return Awaiter<object>.Create(resultProvider =>
        {
            try
            {
                stream.BeginWrite(buffer, offset, numBytes, o =>
                {
                    try
                    {
                        stream.EndWrite(o);
                        resultProvider(AwaiterResult<object>.Completed(null));
                    }
                    catch (Exception exception)
                    {
                        resultProvider(AwaiterResult<object>.Failed(exception));
                    }
                }, null);
            }
            catch (Exception exception)
            {
                resultProvider(AwaiterResult<object>.Failed(exception));
            }
        });
    }
}

public Awaiter<object> WriteFileAwaiter(string path, string text)
{
    return Awaiter<object>.Create(async resultProvider =>
    {
        try
        {
            using (var stream = IsolatedStorageFile.OpenFile(path, FileMode.Create))  
                // caution: in fact the stream is running synchronously on WP7
            {
                var data = Encoding.Unicode.GetBytes(text);
                await stream.BeginWriteAwaiter(data, 0, data.Length);
                resultProvider(AwaiterResult<object>.Completed(null));
            }
        }
        catch (Exception exception)
        {
            resultProvider(AwaiterResult<object>.Failed(exception));
        }
    });
}

I encourage you to download sources with attached samples and play with Async CTP on WP7 because it changes a lot in terms of writing asynchronous code. AsyncCtpLibrary library provides TaskEx class with few very useful methods so you can find counterpart in my library called AwaiterEx with following API:

public static class AwaiterEx
{
    public static Awaiter<string> DownloadStringAwaiter(this WebClient webClient, Uri uri) { ... }
    public static Awaiter<object> BeginWriteAwaiter(this Stream stream, byte[] buffer, int offset, int numBytes) { ... }
  
    public static Awaiter<T> ToAwaiter<T>(this IObservable<T> observable) { ... }
    public static Awaiter<T[]> ToAwaiterAll<T>(this IObservable<T> observable) { ... }
    public static IObservable<T> ToObservable<T>(this Awaiter<T> awaiter) { ... }
    
    public static Awaiter<T[]> WhenAll<T>(this IEnumerable<Awaiter<T>> awaiters) { ... }
    public static Awaiter<T[]> WhenAll<T>(params Awaiter<T>[] awaiters) { ... }
    public static Awaiter<T> Run<T>(Func<T> action) { ... }
    public static Awaiter<object> Delay(TimeSpan timeSpan) { ... }
}

Have fun and let me know if you liked it or not. Download

Thursday, December 9, 2010

Recording of my presentation "Introduction to F#” has been published

Few weeks ago I promised recording of my presentation given during MTS 2010 conference, here it is. Enjoy!

Sunday, November 7, 2010

Currying in C#

During reviewing samples for Async Ctp I have found such code:

var cts = new CancellationTokenSource();
btnCancel.Click += cts.EventHandler;  // !!!!
 
public static class Extensions
{
    public static void EventHandler(this CancellationTokenSource cts, 
        object sender, EventArgs e)
    {
        cts.Cancel();
    }
}

Did you know it was possible ?

Wednesday, October 27, 2010

After Microsoft Technology Summit 2010

This year again I had the opportunity to speak during MTS 2010 conference in Warsaw. Last time I have been talking about WF4 and this time the title of my talk was “Introduction to F#”. I would like to thank all attendees for coming! All resources presented during the session are available for download here, here and here. In the near future I’ll publish recording from this session.

Monday, October 25, 2010

Debugging Reactive Framework (RxDebugger) and Linq to objects (LinqDebugger)

[New version (2011.05.06)]

[Project download has been upgraded to the newest version of Rx (Build v1.0.2787.0) and VS2010 ] download
(Changes: projects converted to VS2010, sample project for RxDebugger added)

In this post I will present two projects LinqDebugger and RxDebugger. Few months ago after reading Bart De Smet’s great post about tracing execution of the Linq to objects queries I was wondering if it was be possible to implement the same concept but in more general way. If we want to trace the execution of all of the Linq operators using described approach we would have to implement many extension methods, one for each Linq operator. How to avoid this ? LinqDebugger is the the answer ;) . If you are wondering what the lazy evaluation is and how to debug Linq to object queries this project can be very useful. Let’s see a very simple query :

var q =
    from i in Enumerable.Range(0, 12)
    where i > 5 && i % 2 == 0
    select i.ToString("C");

foreach (var s in q)
    Console.WriteLine(s);

Now let’s debug that query:

var q =
    from i in Enumerable.Range(0, 12).AsDebuggable()
    where i > 5 && i % 2 == 0
    select i.ToString("C");

foreach (var s in q)
    Console.WriteLine(s); 

After running this code you will find the following text on the console:

Select creation
Select begin
Where creation
Where begin
 predicate i => ((i > 5) && ((i % 2) = 0)) : (0) => False
 predicate i => ((i > 5) && ((i % 2) = 0)) : (1) => False
 predicate i => ((i > 5) && ((i % 2) = 0)) : (2) => False
 predicate i => ((i > 5) && ((i % 2) = 0)) : (3) => False
 predicate i => ((i > 5) && ((i % 2) = 0)) : (4) => False
 predicate i => ((i > 5) && ((i % 2) = 0)) : (5) => False
 predicate i => ((i > 5) && ((i % 2) = 0)) : (6) => True
Where end 6
 selector i => i.ToString("C") : (6) => 6,00 zł
Select end 6,00 zł
6,00 zł
Select begin
Where begin
 predicate i => ((i > 5) && ((i % 2) = 0)) : (7) => False
 predicate i => ((i > 5) && ((i % 2) = 0)) : (8) => True
Where end 8
 selector i => i.ToString("C") : (8) => 8,00 zł
Select end 8,00 zł
8,00 zł
Select begin
Where begin
 predicate i => ((i > 5) && ((i % 2) = 0)) : (9) => False
 predicate i => ((i > 5) && ((i % 2) = 0)) : (10) => True
Where end 10
 selector i => i.ToString("C") : (10) => 10,00 zł
Select end 10,00 zł
10,00 zł
Select begin
Where begin
 predicate i => ((i > 5) && ((i % 2) = 0)) : (11) => False
Where end (no result)
Select end (no result)

This text shows how the query has been executed. There can find there information about enumerators object creation, about data passing from one enumerator to another and execution of all functions used inside the query. One thing worth mentioning is that everything is presented in the same order as it was executed. Having this information we can easily figure out for example in which iteration the exception has been thrown and what were the values processing by the query at that moment. If such text representation is hard to read for you I also provide the VS visualizer for ExecutionPlan type presenting the same information on the tree control (copy LinqDebugger.dll and LinqDebugger.Visualizer.dll files to C:\Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\Visualizers folder to make it available).

var executionPlan = new ExecutionPlan();

var q =
    from i in Enumerable.Range(0, 12).AsDebuggable(executionPlan)
    where i > 5 && i % 2 == 0
    select i.ToString("C");

foreach (var s in q)
    Console.WriteLine(s);

image

I am not going to describe here in details how LinqDebugger has been implemented, you can download the code and check this out yourself. As a hint I will just show you the signature of AsDebuggable method. Please notice what else you can pass to that method. We can choose which operators we want to trace using LinqOperators enum type or pass TextWriter object (Console.Out is set as a default TextWriter).

public static class LinqDebuggerExtensions
{
    public static IQueryable<T> AsDebuggable<T>(this IEnumerable<T> source, ExecutionPlan executionPlan,
        LinqOperators linqOperators, TextWriter textWriter)
    { ... }
}

[Flags]
public enum LinqOperators : long
{
    None = 0,
    Aggregate = 1,
    All = 2,
    Any = 4,
    AsQueryable = 8,
    Average = 16,
    Cast = 32,
    Concat = 64,
    Contains = 128,
    ...
}

[Serializable]
public sealed class ExecutionPlan
{
    public Expression Query { get; internal set; }
    public List<Record> Records { get; }
    public void Reset();
}
    
[Serializable]
public class Record
{
    public RecordType RecordType { get; internal set; }
    public MethodCallExpression OperatorCallExpression { get; internal set; }
    public object Result { get; internal set; }
    public LambdaExpression FuncCallExpression { get; internal set; }
    public string FuncCallName { get; internal set; }
    public object[] Arguments { get; internal set; }
}

Tracing similar information during Rx queries execution is even more useful because in most cases such queries are executed asynchronously so debugging them is really hard. Let’s debug Rx version of previous query using RxDebugger:

var q =
    from i in Enumerable.Range(0, 12).ToObservable().AsDebuggable(
        new DebugSettings {SourceName = "range", Logger = DebugSettings.ConsoleLogger})
    where i > 5 && i % 2 == 0
    select i.ToString("C");

q.Run(Console.WriteLine);


range.Where.Select.Subscribe()
range.Where.Subscribe()
range.Subscribe()
range.OnNext(0)
range.OnNext(1)
range.OnNext(2)
range.OnNext(3)
range.OnNext(4)
range.OnNext(5)
6,00 zł
range.OnNext(6)
range.Where.OnNext(6)
range.Where.Select.OnNext(6,00 zł)
range.OnNext(7)
8,00 zł
range.OnNext(8)
range.Where.OnNext(8)
range.Where.Select.OnNext(8,00 zł)
range.OnNext(9)
10,00 zł
range.OnNext(10)
range.Where.OnNext(10)
range.Where.Select.OnNext(10,00 zł)
range.OnNext(11)
range.OnCompleted()
range.Where.OnCompleted()
range.Where.Select.OnCompleted()
range.Where.Select.Dispose()
range.Where.Dispose()
range.Dispose()

As you can see this time a quite deferent information displayed on the screen and there is no VS visualizer available. It’s because the implementation of RxDebugger is totally different from LinqDebugger. But there are some additional features too. To understand how RxDebugger works I will show you the Debug method which gives us ability to trace single observable object instead of the whole Rx query.

var q =
    from i in Enumerable.Range(0, 12).ToObservable().Debug(
        new DebugSettings {SourceName = "range", Logger = DebugSettings.ConsoleLogger})
    where i > 5 && i % 2 == 0
    select i.ToString("C");

q.Run(Console.WriteLine);

range.Subscribe()
range.OnNext(0)
range.OnNext(1)
range.OnNext(2)
range.OnNext(3)
range.OnNext(4)
range.OnNext(5)
6,00 zł
range.OnNext(6)
range.OnNext(7)
8,00 zł
range.OnNext(8)
range.OnNext(9)
10,00 zł
range.OnNext(10)
range.OnNext(11)
range.OnCompleted()
range.Dispose()

 

public static IObservable<T> Debug<T>(this IObservable<T> source, DebugSettings settings, Func<T, object> valueSelector)
{
    Action<T> onNext = v => { };
    if ((settings.NotificationFilter & NotificationFilter.OnNext) == NotificationFilter.OnNext)
        onNext = v => 
        { 
            if (settings.Logger != null) 
                settings.LoggerScheduler.Schedule(() => settings.Logger(DebugEntry.Create(settings, NotificationFilter.OnNext, valueSelector(v)))); 
        };
        
    Action<Exception> onError = ... ;
    Action onCompleted = ... ;
    Action subscribe = ... ;
    Action dispose = ... ;
    
    return Observable.CreateWithDisposable<T>(o =>
    {
        var newObserver = Observer.Create<T>
        (
            v => { onNext(v); o.OnNext(v); },
            e => { onError(e); o.OnError(e); },
            () => { onCompleted(); o.OnCompleted(); }
        );

        subscribe();
        var disposable = source.Subscribe(newObserver);

        return Disposable.Create(() =>
        {
            dispose();
            disposable.Dispose();
        });
    });
}

public sealed class DebugSettings
{
    // defaults 
    public static Action<DebugEntry> DefaultLogger { get; set; }
    public static IScheduler DefaultLoggerSchduler { get; set; }       
    public static string DefaultMessageFormat { get; set; }

    //loggers
    public static Action<DebugEntry> ConsoleLogger { get; private set; }
    public static Action<DebugEntry> DebugLogger { get; private set; }
   
    public string MessageFormat { get; set; }
    public Action<DebugEntry> Logger { get; set; }
    public IScheduler LoggerScheduler { get; set; }
    public string SourceName { get; set; }
    public NotificationFilter NotificationFilter { get; set; }
    public OperatorFilter OperatorFilter { get; set; }

    static DebugSettings()
    {
        ConsoleLogger = n => Console.WriteLine(n.FormattedMessage);
        DebugLogger = n => Debug.WriteLine(n.FormattedMessage);

        DefaultLogger = DebugLogger;
        DefaultLoggerSchduler = Scheduler.CurrentThread;
        DefaultMessageFormat = "{0}.{1}({2})";
    }

    public DebugSettings()
    {
        SourceName = "";
        NotificationFilter = NotificationFilter.All;
        OperatorFilter = OperatorFilter.AllOperators;

        Logger = DefaultLogger;
        LoggerScheduler = DefaultLoggerSchduler;
        MessageFormat = DefaultMessageFormat;
    }
}

public class DebugEntry
{
    public string SourceName { get; set; }
    public string FormattedMessage { get; set; }
    public NotificationFilter Kind { get; set; }
    public Exception Exception { get; set; }
    public object Value { get; set; }
}

Debug method creates a new observable object on the top of given observable sources. Each observer passed to this observable source is wrapped into a new observer tracing information about calling Subscribe, Dispose methods at the IObservable level and OnNext, OnError, OnCompleted methods at the IObserver level. We can provide filter on Rx operators (OperatorFilter enum type) or logged information (NotificationFilter enum type). In LinqDebugger project TextWiter class has been used to log information. Here we have much more flexible solution because we can pass delegate type responsible for storing logged information. RxDebugger provides standard loggers such as DebugSettings.ConsoleLogger or DebugSettings.DebugLogger but we can also set our own delegate type or even merge many different logger delegates. Such a scenario will be presented in further part of the post. Once we know how Debug method works let’s reveal the secret behind the AsDebuggable method.

public interface IDebuggedObservable<T> : IObservable<T>
{
    DebugSettings Settings { get; }
}
    
public static partial class RxDebuggerExtensions
{    
    public static IDebuggedObservable<T> AsDebuggable<T>(this IObservable<T> source, DebugSettings settings)
    {
        return new DebuggedObservable<T>(source.Debug(settings), settings);
    }
        
    public static IDebuggedObservable<TSource> Where<TSource>(this IDebuggedObservable<TSource> source , Func<TSource,bool> predicate)
    {
        var settings = source.Settings.Copy();
        settings.SourceName = settings.SourceName +  ".Where";
        return new DebuggedObservable<TSource>((source as IObservable<TSource>).Where<TSource>(predicate).Debug(settings), settings);
    }
    public static IDebuggedObservable<TResult> Select<TSource,TResult>(this IDebuggedObservable<TSource> source , Func<TSource,TResult> selector)
    {
        var settings = source.Settings.Copy();
        settings.SourceName = settings.SourceName +  ".Select";
        return new DebuggedObservable<TResult>((source as IObservable<TSource>).Select<TSource,TResult>(selector).Debug(settings), settings);
    } 
    ... 
    
    private class DebuggedObservable<T> : IDebuggedObservable<T>
    {
        private readonly IObservable<T> _source;
        private readonly DebugSettings _settings;
        public DebugSettings Settings { get { return _settings; } }

        public DebuggedObservable(IObservable<T> source, DebugSettings settings)
        {
            _source = source;
            _settings = settings;
        }
        public IDisposable Subscribe(IObserver<T> observer)
        {
            return _source.Subscribe(observer);
        }            
    }
}

Of course I didn’t implement extension methods for all Rx operator manually, I wrote T4 template generating appropriate extension methods (currently 127 methods in .Net version and 125 methods in Silverlight version :) ). The best way to use RxDebugger in your projects is to add T4 template to the project you are working on and run template every time you change the version of Rx. It allows you to always be synchronized with Rx dlls. Finally let’s see how to use RxDebugger in Silverlight application.

<UserControl x:Class="Blog.SL.Post016.RxDebuggerTest"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
    <StackPanel>
        <TextBox x:Name="input"/>
        <TextBox x:Name="output"/>
        <ItemsControl x:Name="log"/>
    </StackPanel>
</UserControl>

 

public partial class RxDebuggerTest : UserControl
{
    public RxDebuggerTest()
    {
        InitializeComponent();

        var entries = new ObservableCollection<DebugEntry>();
        log.ItemsSource = entries;

        var q = input
            .GetObservableTextChanged()
            .Select(e => ((TextBox)e.Sender).Text)
            .AsDebuggable(new DebugSettings
                              {
                                  SourceName = "textChanged", 
                                  LoggerScheduler = Scheduler.Dispatcher, 
                                  Logger = DebugSettings.DebugLogger + entries.Add,                                      
                              })
            .Throttle(TimeSpan.FromSeconds(2))
            .Select(t => new string(t.Reverse().ToArray()));

        q.ObserveOnDispatcher().Subscribe(t => output.Text = t);
    }
}

image

And that’s it for the post. I encourage you to download and play with the two simple tools I provided here. They can be very helpful in debugging LINQ quires or learning about the internals of LINQ and Rx.
downlaod (Rx versions: .Net3.5 v1.0.2698.0 and SL3 v1.0.2698.0) Always check for newest version at the beginning of the post.

Monday, July 5, 2010

After Virtual Study Conference 2010

VirtualStudy Conference 2010 was the first edition of the virtual conference where all attendees as well as speakers have been remotely connected together via Live Meeting platform. This time I have been talking about reactive programming  as a general way of writing code. Here is the overview of my presentation:

Reactive Programming - a new paradigm of programming

Nowadays more and more systems created by us work in the cloud. Client while connecting using WebService is performing certain operations. Remote calls have longer time of duration than local methods, so often we are forced to perform them asynchronously. .NET Framework provides mechanisms, such as threads, APM pattern (Asynchronous Programming Model) or EAP (Event-based Asynchronous Pattern.) But the problem arises, when we want to coordinate a number of simultaneous asynchronous requests. What will happen in a situation where one of the operations will be canceled, or there is an unexpected error? Code that supports such a scenario becomes unreadable, and thus - difficult in maintenance and testing. During this session we will be presenting several approaches to reactive programming, including Reactive Framework, TPL, asynchronous workflows in F # and AsyncEnumerator project.

As usually code samples and slides are available here and you can watch the presentation here. Enjoy!

Tuesday, March 30, 2010

After Rx Road show

Last week I have finished Rx Road show. I have been giving presentations about Reactive Framework on four Polish .Net Users Groups: in Wroclaw, Lodz, Krakow and Chorzow. Thank you all for coming to my session and filling the evaluations, I hope you have learned something useful about Rx during the session. I have also good news for those of you who were interested in my presentation but for some reason couldn’t come, one of the presentation has been recorded and it is now available for download or watching live online here. Slides and all code samples can be download from here. Enjoy!