Thursday, December 30, 2021

Exiting vim editor

1. Press the Esc key.

2. You should see the ––INSERT–– label vanish from the lower-left.

3. Press either of these options

:w – write out changes that were made

:q – exit Vim

:q! – exit Vim and discard any changes

:wq – saves the changes, and exits Vim

:x – save the changes made, and exits Vim


Exit Vim Using a Shortcut Key

In addition to command mode, Vim also has the option for shortcut keys:

To save a file in Vim and exit, press Esc then "Shift + ZZ"

To exit Vim without saving, press Esc then press "Shift + ZX"

Tuesday, August 11, 2015

Reactive Extension(Rx) Examples

Reactive Extension(Rx) Examples

Asynchronous Background Operations

Start - Run Code Asynchronously

public static async void StartBackgroundWork() {
    Console.WriteLine("Shows use of Start to start on a background thread:");
    var o = Observable.Start(() =>
    {
        //This starts on a background thread.
        Console.WriteLine("From background thread. Does not block main thread.");
        Console.WriteLine("Calculating...");
        Thread.Sleep(1000);
        Console.WriteLine("Background work completed.");
    });
    await o.FirstAsync();   // subscribe and wait for completion of background operation.  If you remove await, the main thread will complete first.
    Console.WriteLine("Main thread completed.");
}

Run a method asynchronously on demand

Execute a long-running method asynchronously. The method does not start running until there is a subscriber. The method is started every time the observable is created and subscribed, so there could be more than one running at once.
// Synchronous operation
public DataType DoLongRunningOperation(string param)
{
    ...
}

public IObservable<DataType> LongRunningOperationAsync(string param)
{
    return Observable.Create<DataType>(
        o => Observable.ToAsync<string,DataType>(DoLongRunningOperation)(param).Subscribe(o)
    );
}

CombineLatest - Parallel Execution

Merges the specified observable sequences into one observable sequence by emitting a list with the latest source elements whenever any of the observable sequences produces an element.
var o = Observable.CombineLatest(
    Observable.Start(() => { Console.WriteLine("Executing 1st on Thread: {0}", Thread.CurrentThread.ManagedThreadId); return "Result A"; }),
    Observable.Start(() => { Console.WriteLine("Executing 2nd on Thread: {0}", Thread.CurrentThread.ManagedThreadId); return "Result B"; }),
    Observable.Start(() => { Console.WriteLine("Executing 3rd on Thread: {0}", Thread.CurrentThread.ManagedThreadId); return "Result C"; }) 
).Finally(() => Console.WriteLine("Done!"));

foreach (string r in o.First())
    Console.WriteLine(r);

Result
Executing 1st on Thread: 3
Executing 2nd on Thread: 4
Executing 3rd on Thread: 3
Done!
Result A
Result B
Result C Note Was ForkJoin which is no longer supported. CombineLatest gives the same result.)

Create With Disposable & Scheduler - Canceling an asynchronous operation

This sample starts a background operation that generates a sequence of integers until it is canceled by the main thread. To start the background operation new the Scheduler class is used and a CancellationTokenSource is indirectly created by a Observable.Create.
Please check out the MSDN documentation on System.Threading.CancellationTokenSource to learn more about cancellation source.
IObservable<int> ob =
    Observable.Create<int>(o =>
        {
            var cancel = new CancellationDisposable(); // internally creates a new CancellationTokenSource
            NewThreadScheduler.Default.Schedule(() =>
                {
                    int i = 0;
                    for (; ; )
                    {
                        Thread.Sleep(200);  // here we do the long lasting background operation
                        if (!cancel.Token.IsCancellationRequested)    // check cancel token periodically
                            o.OnNext(i++);
                        else
                        {
                            Console.WriteLine("Aborting because cancel event was signaled!");
                            o.OnCompleted();
                            return;
                        }
                    }
                }
            );

            return cancel;
        }
    );

IDisposable subscription = ob.Subscribe(i => Console.WriteLine(i));
Console.WriteLine("Press any key to cancel");
Console.ReadKey();
subscription.Dispose();
Console.WriteLine("Press any key to quit");
Console.ReadKey();  // give background thread chance to write the cancel acknowledge message

Observation Operators

Observing an Event - Simple

class ObserveEvent_Simple
{
    public static event EventHandler SimpleEvent;
    static void Main()
    {
        // To consume SimpleEvent as an IObservable:
        IObservable<EventPattern<EventArgs>> eventAsObservable = Observable.FromEventPattern(
        ev => SimpleEvent += ev,
        ev => SimpleEvent -= ev);
    }
}

Alternately, you can use EventArgs:
public static event EventHandler<EventArgs> SimpleEvent;

private static void Main(string[] args) {
    IObservable<EventPattern<EventArgs>> eventAsObservable = Observable.FromEventPattern<EventArgs>
        (ev => SimpleEvent += ev,
         ev => SimpleEvent -= ev);
 }

Observing an Event - Simple (expanded)

class ObserveEvent_Simple
{
    public static event EventHandler SimpleEvent;

    private static void Main()
    {
        Console.WriteLine("Setup observable");
        // To consume SimpleEvent as an IObservable:
        IObservable<EventPattern<EventArgs>> eventAsObservable = Observable.FromEventPattern(
                ev => SimpleEvent += ev,
                ev => SimpleEvent -= ev);

        // SimpleEvent is null until we subscribe
        Console.WriteLine(SimpleEvent == null ? "SimpleEvent == null" : "SimpleEvent != null");

        Console.WriteLine("Subscribe");
        //Create two event subscribers
        var s = eventAsObservable.Subscribe(args => Console.WriteLine("Received event for s subscriber"));
        var t = eventAsObservable.Subscribe(args => Console.WriteLine("Received event for t subscriber"));

        // After subscribing the event handler has been added
        Console.WriteLine(SimpleEvent == null ? "SimpleEvent == null" : "SimpleEvent != null");

        Console.WriteLine("Raise event");
        if (null != SimpleEvent)
        {
            SimpleEvent(null, EventArgs.Empty);
        }

        // Allow some time before unsubscribing or event may not happen
        Thread.Sleep(100);

        Console.WriteLine("Unsubscribe");
        s.Dispose();
        t.Dispose();

        // After unsubscribing the event handler has been removed
        Console.WriteLine(SimpleEvent == null ? "SimpleEvent == null" : "SimpleEvent != null");

        Console.ReadKey();
    }
}

Observing MouseMove in Silverlight

var mouseMove = Observable.FromEventPattern<MouseEventArgs>(this, "MouseMove");
mouseMove.ObserveOnDispatcher()
         .Subscribe(args => Debug.WriteLine(args.EventArgs.GetPosition(this)));

Note that a reference to System.Reactive.Windows.Threading is required for ObserveOnDispatcher which is in Nuget as Reactive Extensions - Silverlight Helpers.

Observing an Event - Generic

class ObserveEvent_Generic
{
    public class SomeEventArgs : EventArgs { }
    public static event EventHandler<SomeEventArgs> GenericEvent;

    static void Main()
    {
        // To consume GenericEvent as an IObservable:
        IObservable<EventPattern<SomeEventArgs>> eventAsObservable = Observable.FromEventPattern<SomeEventArgs>(
            ev => GenericEvent += ev,
            ev => GenericEvent -= ev );
    }
}

Observing an Event - Non-Generic

class ObserveEvent_NonGeneric
{
    public class SomeEventArgs : EventArgs { }
    public delegate void SomeNonGenericEventHandler(object sender, SomeEventArgs e);
    public static event SomeNonGenericEventHandler NonGenericEvent;

    static void Main()
    {
        // To consume NonGenericEvent as an IObservable, first inspect the type of EventArgs used in the second parameter of the delegate.
        // In this case, it is SomeEventArgs.  Then, use as shown below.
        IObservable<IEvent<SomeEventArgs>> eventAsObservable = Observable.FromEvent(
            (EventHandler<SomeEventArgs> ev) => new SomeNonGenericEventHandler(ev), 
            ev => NonGenericEvent += ev,
            ev => NonGenericEvent -= ev);
    }
}

Observing an Asynchronous Operation

class Observe_IAsync
{
    static void Main()
    {
        // We will use Stream's BeginRead and EndRead for this sample.
        Stream inputStream = Console.OpenStandardInput();

        // To convert an asynchronous operation that uses the IAsyncResult pattern to a function that returns an IObservable, use the following format.  
        // For the generic arguments, specify the types of the arguments of the Begin* method, up to the AsyncCallback.
        // If the End* method returns a value, append this as your final generic argument.
        var read = Observable.FromAsyncPattern<byte[], int, int, int>(inputStream.BeginRead, inputStream.EndRead);

        // Now, you can get an IObservable instead of an IAsyncResult when calling it.
        byte[] someBytes = new byte[10];
        IObservable<int> observable = read(someBytes, 0, 10);
    }
}
Be aware that while the code above formally provides an observable, this is not enough for most intended uses. For more information, see
Creating an observable sequence and
c# - What is the proper way to create an Observable which reads a stream to the end - Stack Overflow.

Observing a Generic IEnumerable

class Observe_GenericIEnumerable
{
    static void Main()
    {
        IEnumerable<int> someInts = new List<int> { 1, 2, 3, 4, 5 };

        // To convert a generic IEnumerable into an IObservable, use the ToObservable extension method.
        IObservable<int> observable = someInts.ToObservable();
    }
}

Observing a Non-Generic IEnumerable - Single Type

class Observe_NonGenericIEnumerableSingleType
{
    static void Main()
    {
        IEnumerable someInts = new object[] { 1, 2, 3, 4, 5 };

        // To convert a non-generic IEnumerable that contains elements of a single type,
        // first use Cast<> to change the non-generic enumerable into a generic enumerable,
        // then use ToObservable.
        IObservable<int> observable = someInts.Cast<int>().ToObservable();
    }
}

Observing a Non-Generic IEnumerable - Multiple Types

Observing the Passing of Time

class Observe_Time
{
    static void Main()
    {
        // To observe time passing, use the Observable.Interval function.
        // It will notify you on a time interval you specify.

        // 0 after 1s, 1 after 2s, 2 after 3s, etc.
        IObservable<long> oneNumberPerSecond = Observable.Interval(TimeSpan.FromSeconds(1));
        IObservable<long> alsoOneNumberPerSecond = Observable.Interval(1000 /* milliseconds */);
    }
}

Restriction Operators

Where - Simple

class Where_Simple
{
    static void Main()
    {
        var oneNumberPerSecond = Observable.Interval(TimeSpan.FromSeconds(1));

        var lowNums = from n in oneNumberPerSecond
                      where n < 5
                      select n;

        Console.WriteLine("Numbers < 5:");

        lowNums.Subscribe(lowNum =>
        {
            Console.WriteLine(lowNum);
        });

        Console.ReadKey();
    }
}

Result
Numbers < 5:
0 (after 1s)
1 (after 2s)
2 (after 3s)
3 (after 4s)
4 (after 5s)

Where - Drilldown

class Where_DrillDown
{
    class Customer
    {
        public Customer() { Orders = new ObservableCollection<Order>(); }
        public string CustomerName { get; set; }
        public string Region { get; set; }
        public ObservableCollection<Order> Orders { get; private set; }
    }

    class Order
    {
        public int OrderId { get; set; }
        public DateTimeOffset OrderDate { get; set; }
    }

    static void Main()
    {
        var customers = new ObservableCollection<Customer>();

        var customerChanges = Observable.FromEventPattern(
            (EventHandler<NotifyCollectionChangedEventArgs> ev)
               => new NotifyCollectionChangedEventHandler(ev),
            ev => customers.CollectionChanged += ev,
            ev => customers.CollectionChanged -= ev);

        var watchForNewCustomersFromWashington =
            from c in customerChanges
            where c.EventArgs.Action == NotifyCollectionChangedAction.Add
            from cus in c.EventArgs.NewItems.Cast<Customer>().ToObservable()
            where cus.Region == "WA"
            select cus;

        Console.WriteLine("New customers from Washington and their orders:");

        watchForNewCustomersFromWashington.Subscribe(cus =>
        {
            Console.WriteLine("Customer {0}:", cus.CustomerName);

            foreach (var order in cus.Orders)
            {
                Console.WriteLine("Order {0}: {1}", order.OrderId, order.OrderDate);
            }
        });

        customers.Add(new Customer
        {
            CustomerName = "Lazy K Kountry Store",
            Region = "WA",
            Orders = { new Order { OrderDate = DateTimeOffset.Now, OrderId = 1 } }
        });

        Thread.Sleep(1000);
        customers.Add(new Customer
        {
            CustomerName = "Joe's Food Shop",
            Region = "NY",
            Orders = { new Order { OrderDate = DateTimeOffset.Now, OrderId = 2 } }
        });

        Thread.Sleep(1000);
        customers.Add(new Customer
        {
            CustomerName = "Trail's Head Gourmet Provisioners",
            Region = "WA",
            Orders = { new Order { OrderDate = DateTimeOffset.Now, OrderId = 3 } }
        });

        Console.ReadKey();
    }
}

Result
New customers from Washington and their orders:
Customer Lazy K Kountry Store: (after 0s)
Order 1: 11/20/2009 11:52:02 AM -06:00
Customer Trail's Head Gourmet Provisioners: (after 2s)
Order 3: 11/20/2009 11:52:04 AM -06:00

Projection Operators

Select - Simple

class Select_Simple
{
    static void Main()
    {
        var oneNumberPerSecond = Observable.Interval(TimeSpan.FromSeconds(1));

        var numbersTimesTwo = from n in oneNumberPerSecond
                              select n * 2;

        Console.WriteLine("Numbers * 2:");

        numbersTimesTwo.Subscribe(num =>
        {
            Console.WriteLine(num);
        });

        Console.ReadKey();
    }
}

Result
Numbers * 2:
0 (after 1s)
2 (after 2s)
4 (after 3s)
6 (after 4s)
8 (after 5s)

Select - Transformation

class Select_Transform
{
    static void Main()
    {
        var oneNumberPerSecond = Observable.Interval(TimeSpan.FromSeconds(1));

        var stringsFromNumbers = from n in oneNumberPerSecond
                                 select new string('*', (int)n);

        Console.WriteLine("Strings from numbers:");

        stringsFromNumbers.Subscribe(num =>
        {
            Console.WriteLine(num);
        });

        Console.ReadKey();
    }
}

Result
Strings from numbers:
(after 0s)
* (after 1s)
** (after 2s)
*** (after 3s)
**** (after 4s)
***** (after 5s)
****** (after 6s)

Select - Indexed

class Where_Indexed
{
    class TimeIndex
    {
        public TimeIndex(int index, DateTimeOffset time)
        {
            Index = index;
            Time = time;
        }
        public int Index { get; set; }
        public DateTimeOffset Time { get; set; }
    }

    static void Main()
    {
        var clock = Observable.Interval(TimeSpan.FromSeconds(1))
            .Select((t, index) => new TimeIndex(index, DateTimeOffset.Now));

        clock.Subscribe(timeIndex =>
        {
            Console.WriteLine(
                "Ding dong.  The time is now {0:T}.  This is event number {1}.",
                timeIndex.Time,
                timeIndex.Index);
        });

        Console.ReadKey();
    }
}

Result
Ding dong. The time is now 1:55:00 PM. This is event number 0. (after 0s)
Ding dong. The time is now 1:55:01 PM. This is event number 1. (after 1s)
Ding dong. The time is now 1:55:02 PM. This is event number 2. (after 2s)
Ding dong. The time is now 1:55:03 PM. This is event number 3. (after 3s)
Ding dong. The time is now 1:55:04 PM. This is event number 4. (after 4s)
Ding dong. The time is now 1:55:05 PM. This is event number 5. (after 5s)

Grouping

Group By - Simple

This example counts how many time you press each key as you furiously hit the keyboard. :)
class GroupBy_Simple
{
    static IEnumerable<ConsoleKeyInfo> KeyPresses()
    {
        for (; ; )
        {
            var currentKey = Console.ReadKey(true);

            if (currentKey.Key == ConsoleKey.Enter)
                yield break;
            else
                yield return currentKey;
        }
    }
    static void Main()
    {
        var timeToStop = new ManualResetEvent(false);
        var keyPresses = KeyPresses().ToObservable();

        var groupedKeyPresses =
            from k in keyPresses
            group k by k.Key into keyPressGroup
            select keyPressGroup;

        Console.WriteLine("Press Enter to stop.  Now bang that keyboard!");

        groupedKeyPresses.Subscribe(keyPressGroup =>
        {
            int numberPresses = 0;

            keyPressGroup.Subscribe(keyPress =>
            {
                Console.WriteLine(
                    "You pressed the {0} key {1} time(s)!",
                    keyPress.Key,
                    ++numberPresses);
            },
            () => timeToStop.Set());
        });

        timeToStop.WaitOne();
    }
}

Result
Depends on what you press! But something like:
Press Enter to stop. Now bang that keyboard!
You pressed the A key 1 time(s)!
You pressed the A key 2 time(s)!
You pressed the B key 1 time(s)!
You pressed the B key 2 time(s)!
You pressed the C key 1 time(s)!
You pressed the C key 2 time(s)!
You pressed the C key 3 time(s)!
You pressed the A key 3 time(s)!
You pressed the B key 3 time(s)!
You pressed the A key 4 time(s)!
You pressed the A key 5 time(s)!
You pressed the C key 4 time(s)!

Time-Related Operators

Buffer - Simple

Buffer has a strange name, but a simple concept.
Imagine an email program that checks for new mail every 5 minutes. While you can receive mail at any instant in time, you only get a batch of emails at every five minute mark.
Let's use Buffer to simulate this.
class Buffer_Simple
{
    static IEnumerable<string> EndlessBarrageOfEmail()
    {
        var random = new Random();
        var emails = new List<String> { "Here is an email!", "Another email!", "Yet another email!" };
        for (; ; )
        {
            // Return some random emails at random intervals.
            yield return emails[random.Next(emails.Count)];
            Thread.Sleep(random.Next(1000));
        }
    }
    static void Main()
    {
        var myInbox = EndlessBarrageOfEmail().ToObservable();

        // Instead of making you wait 5 minutes, we will just check every three seconds instead. :)
        var getMailEveryThreeSeconds = myInbox.Buffer(TimeSpan.FromSeconds(3)); //  Was .BufferWithTime(...

        getMailEveryThreeSeconds.Subscribe(emails =>
        {
            Console.WriteLine("You've got {0} new messages!  Here they are!", emails.Count());
            foreach (var email in emails)
            {
                Console.WriteLine("> {0}", email);
            }
            Console.WriteLine();
        });

        Console.ReadKey();
    }
}

Result
You've got 5 new messages! Here they are! (after 3s)
> Here is an email!
> Another email!
> Here is an email!
> Another email!
> Here is an email! You've got 6 new messages! Here they are! (after 6s)
> Another email!
> Another email!
> Here is an email!
> Here is an email!
> Another email!
> Another email!

Delay - Simple

class Delay_Simple
{
    static void Main()
    {
        var oneNumberEveryFiveSeconds = Observable.Interval(TimeSpan.FromSeconds(5));

        // Instant echo
        oneNumberEveryFiveSeconds.Subscribe(num =>
        {
            Console.WriteLine(num);
        });

        // One second delay
        oneNumberEveryFiveSeconds.Delay(TimeSpan.FromSeconds(1)).Subscribe(num =>
        {
            Console.WriteLine("...{0}...", num);
        });

        // Two second delay
        oneNumberEveryFiveSeconds.Delay(TimeSpan.FromSeconds(2)).Subscribe(num =>
        {
            Console.WriteLine("......{0}......", num);
        });

        Console.ReadKey();
    }
}

Result
0 (after 5s)
…0… (after 6s)
……0…… (after 7s)
1 (after 10s)
…1… (after 11s)
……1…… (after 12s)

Interval - Simple

internal class Interval_Simple
{
    private static void Main()
    {
        IObservable<long> observable = Observable.Interval(TimeSpan.FromSeconds(1));

        using (observable.Subscribe(Console.WriteLine))
        {
            Console.WriteLine("Press any key to unsubscribe");
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

Result
0 (after 1s)
1 (after 2s)
2 (after 3s)
3 (after 4s)

Sample - Simple

internal class Sample_Simple
{
    private static void Main()
    {
        // Generate sequence of numbers, (an interval of 50 ms seems to result in approx 16 per second).
        IObservable<long> observable = Observable.Interval(TimeSpan.FromMilliseconds(50));

        // Sample the sequence every second
        using (observable.Sample(TimeSpan.FromSeconds(1)).Timestamp().Subscribe(
            x => Console.WriteLine("{0}: {1}", x.Value, x.Timestamp)))
        {
            Console.WriteLine("Press any key to unsubscribe");
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

Result
15: 24/11/2009 15:40:45 (after 1s)
31: 24/11/2009 15:40:46 (after 2s)
47: 24/11/2009 15:40:47 (after 3s)
64: 24/11/2009 15:40:48 (after 4s)

Throttle - Simple

Throttle stops the flow of events until no more events are produced for a specified period of time. For example, if you throttle a TextChanged event of a textbox to .5 seconds, no events will be passed until the user has stopped typing for .5 seconds. This is useful in search boxes where you do not want to start a new search after every keystroke, but want to wait until the user pauses.
SearchTextChangedObservable = Observable.FromEventPattern<TextChangedEventArgs>(this.textBox, "TextChanged");
_currentSubscription = SearchTextChangedObservable.Throttle(TimeSpan.FromSeconds(.5)).ObserveOnDispatcher().Subscribe(e => this.ListItems.Add(this.textBox.Text));
Here is another example:
internal class Throttle_Simple
{
    // Generates events with interval that alternates between 500ms and 1000ms every 5 events
    static IEnumerable<int> GenerateAlternatingFastAndSlowEvents()
    {
        int i = 0;

        while(true)
        {
            if(i > 1000)
            {
                yield break;
            }
            yield return i;
            Thread.Sleep( i++ % 10 < 5 ? 500 : 1000);
        }
    }

    private static void Main()
    {
        var observable = GenerateAlternatingFastAndSlowEvents().ToObservable().Timestamp();
        var throttled = observable.Throttle(TimeSpan.FromMilliseconds(750));

        using (throttled.Subscribe(x => Console.WriteLine("{0}: {1}", x.Value, x.Timestamp)))
        {
            Console.WriteLine("Press any key to unsubscribe");
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

Result
5: <timestamp>
6: <timestamp>
7: <timestamp>
8: <timestamp>
9: <timestamp>
15: <timestamp>
16: <timestamp>
17: <timestamp>
18: <timestamp>
19: <timestamp>
…etc

Interval - With TimeInterval() - Simple

internal class TimeInterval_Simple
{
    // Like TimeStamp but gives the time-interval between successive values
    private static void Main()
    {
        var observable = Observable.Interval(TimeSpan.FromMilliseconds(750)).TimeInterval();

        using (observable.Subscribe(
            x => Console.WriteLine("{0}: {1}", x.Value, x.Interval)))
        {
            Console.WriteLine("Press any key to unsubscribe");
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

Result
0: 00:00:00.8090459 (1st value)
1: 00:00:00.7610435 (2nd value)
2: 00:00:00.7650438 (3rd value)

Interval - With TimeInterval() - Remove

internal class TimeInterval_Remove
{
    private static void Main()
    {
        // Add a time interval
        var observable = Observable.Interval(TimeSpan.FromMilliseconds(750)).TimeInterval();

        // Remove it again
        using (observable.RemoveTimeInterval().Subscribe(Console.WriteLine))
        {
            Console.WriteLine("Press any key to unsubscribe");
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

Result
0
1
2

Timeout - Simple

internal class Timeout_Simple
{
    private static void Main()
    {
        Console.WriteLine(DateTime.Now);

        // create a single event in 10 seconds time
        var observable = Observable.Timer(TimeSpan.FromSeconds(10)).Timestamp();

        // raise exception if no event received within 9 seconds
        var observableWithTimeout = Observable.Timeout(observable, TimeSpan.FromSeconds(9));

        using (observableWithTimeout.Subscribe(
            x => Console.WriteLine("{0}: {1}", x.Value, x.Timestamp), 
            ex => Console.WriteLine("{0} {1}", ex.Message, DateTime.Now)))
        {
            Console.WriteLine("Press any key to unsubscribe");
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

Result
02/12/2009 10:13:00
Press any key to unsubscribe
The operation has timed out. 02/12/2009 10:13:09

Timer - Simple

Observable.Interval is a simple wrapper around Observable.Timer.
internal class Timer_Simple
{
    private static void Main()
    {
        Console.WriteLine(DateTime.Now);

        var observable = Observable.Timer(TimeSpan.FromSeconds(5), 
                                                       TimeSpan.FromSeconds(1)).Timestamp();

        // or, equivalently
        // var observable = Observable.Timer(DateTime.Now + TimeSpan.FromSeconds(5), 
        //                                                TimeSpan.FromSeconds(1)).Timestamp();

        using (observable.Subscribe(
            x => Console.WriteLine("{0}: {1}", x.Value, x.Timestamp)))
        {
            Console.WriteLine("Press any key to unsubscribe");
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

Result
02/12/2009 10:02:29
Press any key to unsubscribe
0: 02/12/2009 10:02:34(after 5s)
1: 02/12/2009 10:02:35 (after 6s)
2: 02/12/2009 10:02:36 (after 7s)

Timestamp - Simple

Adds a TimeStamp to each element using the system's local time.
internal class Timestamp_Simple
{
    private static void Main()
    {
        var observable = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp();

        using (observable.Subscribe(
            x => Console.WriteLine("{0}: {1}", x.Value, x.Timestamp)))
        {
            Console.WriteLine("Press any key to unsubscribe");
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

Result
0: 24/11/2009 15:40:45 (after 1s)
1: 24/11/2009 15:40:46 (after 2s)
2: 24/11/2009 15:40:47 (after 3s)
3: 24/11/2009 15:40:48 (after 4s)

Timestamp - Remove

internal class Timestamp_Remove
{
    private static void Main()
    {
        // Add timestamp
        var observable = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp();

        // Remove it
        using (observable.RemoveTimestamp().Subscribe(Console.WriteLine))
        {
            Console.WriteLine("Press any key to unsubscribe");
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

Result
0 (after 1s)
1 (after 2s)
2 (after 3s)
3 (after 4s)

Window and Joins

Window

Divides a stream into "Windows" of time. For example, 5 five second window would contain all elements pushed in that five second interval.
IObservable<long> mainSequence = Observable.Interval(TimeSpan.FromSeconds(1));
IObservable<IObservable<long>> seqWindowed = mainSequence.Window(() =>
    {
        IObservable<long> seqWindowControl = Observable.Interval(TimeSpan.FromSeconds(6));
        return seqWindowControl;
    });

seqWindowed.Subscribe(seqWindow =>
    {
        Console.WriteLine("\nA new window into the main sequence has opened: {0}\n",
                            DateTime.Now.ToString());
        seqWindow.Subscribe(x => { Console.WriteLine("Integer : {0}", x); });
    });

Console.ReadLine();

GroupJoin - Joins two streams matching by one of their attributes

var leftList = new List<string[]>();
leftList.Add(new string[] { "2013-01-01 02:00:00", "Batch1" });
leftList.Add(new string[] { "2013-01-01 03:00:00", "Batch2" });
leftList.Add(new string[] { "2013-01-01 04:00:00", "Batch3" });

var rightList = new List<string[]>();
rightList.Add(new string[] { "2013-01-01 01:00:00", "Production=2" });
rightList.Add(new string[] { "2013-01-01 02:00:00", "Production=0" });
rightList.Add(new string[] { "2013-01-01 03:00:00", "Production=3" });

var l = leftList.ToObservable();
var r = rightList.ToObservable();

var q = l.GroupJoin(r,
    _ => Observable.Never<Unit>(), // windows from each left event going on forever
    _ => Observable.Never<Unit>(), // windows from each right event going on forever
    (left, obsOfRight) => Tuple.Create(left, obsOfRight)); // create tuple of left event with observable of right events

// e is a tuple with two items, left and obsOfRight
q.Subscribe(e =>
{
    var xs = e.Item2;
    xs.Where(
     x => x[0] == e.Item1[0]) // filter only when datetime matches
     .Subscribe(
     v =>
     {
        Console.WriteLine(
           string.Format("{0},{1} and {2},{3} occur at the same time",
           e.Item1[0],
           e.Item1[1],
           v[0],
           v[1]
        ));
     });
});

Range

Generates a Range of values. Useful for testing purposes.

Range - Prints from 1 to 10.

IObservable<int> source = Observable.Range(1, 10);
IDisposable subscription = source.Subscribe(
x => Console.WriteLine("OnNext: {0}", x),
ex => Console.WriteLine("OnError: {0}", ex.Message),
() => Console.WriteLine("OnCompleted"));
Console.WriteLine("Press ENTER to unsubscribe...");
Console.ReadLine();
subscription.Dispose();

Generate

There are several overloads for Generate.

Generate - simple

A simple use is to replicate Interval but have the sequence stop.
internal class Generate_Simple
{
    private static void Main()
    {
        var observable =
            Observable.Generate(1, x => x < 6, x => x + 1, x => x, 
                                         x=>TimeSpan.FromSeconds(1)).Timestamp();

        using (observable.Subscribe(x => Console.WriteLine("{0}, {1}", x.Value, x.Timestamp)))
        {
            Console.WriteLine("Press any key to unsubscribe");
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

Result
1: 24/11/2009 15:40:45 (after 1s)
2: 24/11/2009 15:40:46 (after 2s)
3: 24/11/2009 15:40:47 (after 3s)
4: 24/11/2009 15:40:48 (after 4s)
5: 24/11/2009 15:40:49 (after 5s)

ISubject<T> and ISubject<T1, T2>

There are several implementations for ISubject.

Ping Pong Actor Model with ISubject<T1, T2>

using System;
using System.Collections.Generic;
using System.Linq;

namespace RxPingPong
{
    /// <summary>Simple Ping Pong Actor model using Rx </summary>
    /// <remarks>
    /// You'll need to install the Reactive Extensions (Rx) for this to work.
    /// You can get the installer from <see href="http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx"/>
    /// </remarks>
    class Program
    {
        static void Main(string[] args)
        {
            var ping = new Ping();
            var pong = new Pong();

            Console.WriteLine("Press any key to stop ...");

            var pongSubscription = ping.Subscribe(pong);
            var pingSubscription = pong.Subscribe(ping);

            Console.ReadKey();

            pongSubscription.Dispose();
            pingSubscription.Dispose();

            Console.WriteLine("Ping Pong has completed.");
        }
    }

    class Ping : ISubject<Pong, Ping>
    {
        #region Implementation of IObserver<Pong>

        /// <summary>
        /// Notifies the observer of a new value in the sequence.
        /// </summary>
        public void OnNext(Pong value)
        {
            Console.WriteLine("Ping received Pong.");
        }

        /// <summary>
        /// Notifies the observer that an exception has occurred.
        /// </summary>
        public void OnError(Exception exception)
        {
            Console.WriteLine("Ping experienced an exception and had to quit playing.");
        }

        /// <summary>
        /// Notifies the observer of the end of the sequence.
        /// </summary>
        public void OnCompleted()
        {
            Console.WriteLine("Ping finished.");
        }

        #endregion

        #region Implementation of IObservable<Ping>

        /// <summary>
        /// Subscribes an observer to the observable sequence.
        /// </summary>
        public IDisposable Subscribe(IObserver<Ping> observer)
        {
            return Observable.Interval(TimeSpan.FromSeconds(2))
                .Where(n => n < 10)
                .Select(n => this)
                .Subscribe(observer);
        }

        #endregion

        #region Implementation of IDisposable

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            OnCompleted();
        }

        #endregion
    }

    class Pong : ISubject<Ping, Pong>
    {
        #region Implementation of IObserver<Ping>

        /// <summary>
        /// Notifies the observer of a new value in the sequence.
        /// </summary>
        public void OnNext(Ping value)
        {
            Console.WriteLine("Pong received Ping.");
        }

        /// <summary>
        /// Notifies the observer that an exception has occurred.
        /// </summary>
        public void OnError(Exception exception)
        {
            Console.WriteLine("Pong experienced an exception and had to quit playing.");
        }

        /// <summary>
        /// Notifies the observer of the end of the sequence.
        /// </summary>
        public void OnCompleted()
        {
            Console.WriteLine("Pong finished.");
        }

        #endregion

        #region Implementation of IObservable<Pong>

        /// <summary>
        /// Subscribes an observer to the observable sequence.
        /// </summary>
        public IDisposable Subscribe(IObserver<Pong> observer)
        {
            return Observable.Interval(TimeSpan.FromSeconds(1.5))
                .Where(n => n < 10)
                .Select(n => this)
                .Subscribe(observer);
        }

        #endregion

        #region Implementation of IDisposable

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            OnCompleted();
        }

        #endregion
    }
}

Result
1: Ping received Pong.
2: Pong received Ping.
3: Ping received Pong.
4: Pong received Ping.
5: Ping received Pong.

Combination Operators

Merge

The Merge operator combine two or more sequences. In the following example, the two streams are merged into one so that both are printed with one subscription. Also note the use of "using" to wrap the Observable, thus ensuring the subscription is Disposed.
class Merge
{
    private static IObservable<int> Xs
    {
        get { return Generate(0, new List<int> {1, 2, 2, 2, 2}); }
    }

    private static IObservable<int> Ys
    {
        get { return Generate(100, new List<int> {2, 2, 2, 2, 2}); }
    }

    private static IObservable<int> Generate(int initialValue, IList<int> intervals)
    {
        // work-around for Observable.Generate calling timeInterval before resultSelector
        intervals.Add(0); 

        return Observable.Generate(initialValue,
                                   x => x < initialValue + intervals.Count - 1,
                                   x => x + 1,
                                   x => x,
                                   x => TimeSpan.FromSeconds(intervals[x - initialValue]));
    }

    private static void Main()
    {
        Console.WriteLine("Press any key to unsubscribe");

        using (Xs.Merge(Ys).Timestamp().Subscribe(
            z => Console.WriteLine("{0,3}: {1}", z.Value, z.Timestamp),
            () => Console.WriteLine("Completed, press a key")))
        {
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

result
0: 11/12/2009 12:17:44
100: 11/12/2009 12:17:45
1: 11/12/2009 12:17:46
101: 11/12/2009 12:17:47
2: 11/12/2009 12:17:48
102: 11/12/2009 12:17:49
3: 11/12/2009 12:17:50
103: 11/12/2009 12:17:51
4: 11/12/2009 12:17:52
104: 11/12/2009 12:17:53

Publish - Sharing a subscription with multiple Observers

class Publish
{
    private static void Main()
    {
        var unshared = Observable.Range(1, 4);

        // Each subscription starts a new sequence
        unshared.Subscribe(i => Console.WriteLine("Unshared Subscription #1: " + i));
        unshared.Subscribe(i => Console.WriteLine("Unshared Subscription #2: " + i));

        Console.WriteLine();

        // By using publish the subscriptions are shared, but the sequence doesn't start until Connect() is called.
        var shared = unshared.Publish();
        shared.Subscribe(i => Console.WriteLine("Shared Subscription #1: " + i));
        shared.Subscribe(i => Console.WriteLine("Shared Subscription #2: " + i));
        shared.Connect();

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

result
Unshared Subscription #1: 1
Unshared Subscription #1: 2
Unshared Subscription #1: 3
Unshared Subscription #1: 4
Unshared Subscription #2: 1
Unshared Subscription #2: 2
Unshared Subscription #2: 3
Unshared Subscription #2: 4 Shared Subscription #1: 1
Shared Subscription #2: 1
Shared Subscription #1: 2
Shared Subscription #2: 2
Shared Subscription #1: 3
Shared Subscription #2: 3
Shared Subscription #1: 4
Shared Subscription #2: 4

Zip

class Zip
{
    // same code as above for Merge...

    private static void Main()
    {
        Console.WriteLine("Press any key to unsubscribe");

        using (Xs.Zip(Ys, (x, y) => x + y).Timestamp().Subscribe(
            z => Console.WriteLine("{0,3}: {1}", z.Value, z.Timestamp),
            () => Console.WriteLine("Completed, press a key")))
        {
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

result
100: 11/12/2009 12:17:45
102: 11/12/2009 12:17:47
104: 11/12/2009 12:17:49
106: 11/12/2009 12:17:51
108: 11/12/2009 12:17:53

CombineLatest

class CombineLatest
{
    // same code as above for Merge...

    private static void Main()
    {
        Console.WriteLine("Press any key to unsubscribe");

        using (Xs.CombineLatest(Ys, (x, y) => x + y).Timestamp().Subscribe(
            z => Console.WriteLine("{0,3}: {1}", z.Value, z.Timestamp),
            () => Console.WriteLine("Completed, press a key")))
        {
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

result
100: 11/12/2009 12:17:45
101: 11/12/2009 12:17:46
102: 11/12/2009 12:17:47
103: 11/12/2009 12:17:48
104: 11/12/2009 12:17:49
105: 11/12/2009 12:17:50
106: 11/12/2009 12:17:51
107: 11/12/2009 12:17:52
108: 11/12/2009 12:17:53

Concat - cold observable

class ConcatCold
{
    private static IObservable<int> Xs
    {
        get { return Generate(0, new List<int> {0, 1, 1}); }
    }

    private static IObservable<int> Ys
    {
        get { return Generate(100, new List<int> {1, 1, 1}); }
    }

    // same Generate() method as above for Merge...

    private static void Main()
    {
        Console.WriteLine("Press any key to unsubscribe");

        Console.WriteLine(DateTime.Now);

        using (Xs.Concat(Ys).Timestamp().Subscribe(
            z => Console.WriteLine("{0,3}: {1}", z.Value, z.Timestamp),
            () => Console.WriteLine("Completed, press a key")))
        {
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

result
0: 11/12/2009 12:17:45
1: 11/12/2009 12:17:46
2: 11/12/2009 12:17:47
100: 11/12/2009 12:17:48
101: 11/12/2009 12:17:49
102: 11/12/2009 12:17:50

Concat - hot observable

class ConcatHot
{
    private static IObservable<int> Xs
    {
        get { return Generate(0, new List<int> {0, 1, 1}); }
    }

    private static IObservable<int> Ys
    {
        get { return Generate(100, new List<int> {1, 1, 1}).Publish(); }
    }

    // same Generate() method as above for Merge...

    private static void Main()
    {
        Console.WriteLine("Press any key to unsubscribe");

        Console.WriteLine(DateTime.Now);

        using (Xs.Concat(Ys).Timestamp().Subscribe(
            z => Console.WriteLine("{0,3}: {1}", z.Value, z.Timestamp),
            () => Console.WriteLine("Completed, press a key")))
        {
            Console.ReadKey();
        }

        Console.WriteLine("Press any key to exit");
        Console.ReadKey();
    }
}

result
0: 11/12/2009 12:17:45
1: 11/12/2009 12:17:46
2: 11/12/2009 12:17:47
102: 11/12/2009 12:17:48

Make your class native to IObservable<T>

If you are about to build new system, you could consider using just IObservable<T>.

Use Subject<T> as backend for IObservable<T>

class UseSubject
{
    public class Order
    {            
        private DateTime? _paidDate;

        private readonly Subject<Order> _paidSubj = new Subject<Order>();
        public IObservable<Order> Paid { get { return _paidSubj.AsObservable(); } }

        public void MarkPaid(DateTime paidDate)
        {
            _paidDate = paidDate;                
            _paidSubj.OnNext(this); // Raise PAID event
        }
    }

    private static void Main()
    {
        var order = new Order();
        order.Paid.Subscribe(_ => Console.WriteLine("Paid")); // Subscribe

        order.MarkPaid(DateTime.Now);
    }
}

Wednesday, December 3, 2014

TCP/IP Datagrams

IP Datagram General Format 


Data transmitted over an internet using IP is carried in messages called IP datagrams. Like all network protocol messages, IP uses a specific format for its datagrams. We are of course looking here at IP version 4 and so we will examine the IPv4 datagram format, which was defined in RFC 791 along with the rest of IPv4.
The IPv4 datagram is conceptually divided into two pieces: the header and the payload. The header contains addressing and control fields, while the payload carries the actual data to be sent over the internetwork. Unlike some message formats, IP datagrams do not have a footer following the payload.
Even though IP is a relatively simple, connectionless, “unreliable” protocol, the IPv4 header carries a fair bit of information, which makes it rather large. At a minimum, it is 20 bytes long, and with options can be significantly longer. The IP datagram format is described in Table 56 and illustrated in Figure 86.

Table 56: Internet Protocol Version 4 (IPv4) Datagram Format
Field Name
Size (bytes)
Description
Version
1/2
(4 bits)
Version: Identifies the version of IP used to generate the datagram. For IPv4, this is of course the number 4. The purpose of this field is to ensure compatibility between devices that may be running different versions of IP. In general, a device running an older version of IP will reject datagrams created by newer implementations, under the assumption that the older version may not be able to interpret the newer datagram correctly.
IHL
1/2
(4 bits)
Internet Header Length (IHL): Specifies the length of the IP header, in 32-bit words. This includes the length of any options fields and padding. The normal value of this field when no options are used is 5 (5 32-bit words = 5*4 = 20 bytes). Contrast to the longer Total Length field below.
TOS
1
Type Of Service (TOS): A field designed to carry information to provide quality of service features, such as prioritized delivery, for IP datagrams. It was never widely used as originally defined, and its meaning has been subsequently redefined for use by a technique called Differentiated Services (DS). See below for more information.
TL
2
Total Length (TL): Specifies the total length of the IP datagram, in bytes. Since this field is 16 bits wide, the maximum length of an IP datagram is 65,535 bytes, though most are much smaller.
Identification
2
Identification: This field contains a 16-bit value that is common to each of the fragments belonging to a particular message; for datagrams originally sent unfragmented it is still filled in, so it can be used if the datagram must be fragmented by a router during delivery. This field is used by the recipient to reassemble messages without accidentally mixing fragments from different messages. This is needed because fragments may arrive from multiple messages mixed together, since IP datagrams can be received out of order from any device. See the discussion of IP message fragmentation.
Flags
3/8
(3 bits)


Fragment Offset
1 5/8
(13 bits)
Fragment Offset: When fragmentation of a message occurs, this field specifies the offset, or position, in the overall message where the data in this fragment goes. It is specified in units of 8 bytes (64 bits). The first fragment has an offset of 0. Again, see the discussion of fragmentation for a description of how the field is used.
TTL
1
Time To Live (TTL): Short version: Specifies how long the datagram is allowed to “live” on the network, in terms of router hops. Each router decrements the value of the TTL field (reduces it by one) prior to transmitting it. If the TTL field drops to zero, the datagram is assumed to have taken too long a route and is discarded.

See below for the longer explanation of TTL.
Protocol
1


Header Checksum
2
Header Checksum: A checksum computed over the header to provide basic protection against corruption in transmission. This is not the more complex CRC code typically used by data link layer technologies such as Ethernet; it's just a 16-bit checksum. It is calculated by dividing the header bytes into words (a word is two bytes) and then adding them together. The data is not checksummed, only the header. At each hop the device receiving the datagram does the same checksum calculation and on a mismatch, discards the datagram as damaged.
Source Address
4
Source Address: The 32-bit IP address of the originator of the datagram. Note that even though intermediate devices such as routers may handle the datagram, they do not normally put their address into this field—it is always the device that originally sent the datagram.
Destination Address
4
Destination Address: The 32-bit IP address of the intended recipient of the datagram. Again, even though devices such as routers may be the intermediate targets of the datagram, this field is always for the ultimate destination.
Options
Variable
Options: One or more of several types of options may be included after the standard headers in certain IP datagrams. I discuss them in the topic that follows this one.
Padding
Variable
Padding: If one or more options are included, and the number of bits used for them is not a multiple of 32, enough zero bits are added to “pad out” the header to a multiple of 32 bits (4 bytes).
Data
Variable
Data: The data to be transmitted in the datagram, either an entire higher-layer message or a fragment of one.


Figure 86: Internet Protocol Version 4 (IPv4) Datagram Format
This diagram shows graphically the all-important IPv4 datagram format. The first 20 bytes are the fixed IP header, followed by an optional Options section, and a variable-length Data area. Note that the Type Of Service field is shown as originally defined in the IPv4 standard.


That’s a pretty big table, because the IP datagram format is pretty important and has a lot of fields that need explaining. To keep it from being even longer, I decided to move a couple of the more complex descriptions out of the table.

Time To Live (TTL) Field

Since IP datagrams are sent from router to router as they travel across an internetwork, it is possible that a situation could result where a datagram gets passed from router A to router B to router C and then back to router A. Router loops are not supposed to happen, and rarely do, but are possible.
To ensure that datagrams don't circle around endlessly, the TTL field was intended to be filled in with a time value (in seconds) when a datagram was originally sent. Routers would decrease the time value periodically, and if it ever hit zero, the datagram would be destroyed. This was also intended to be used to ensure that time-critical datagrams wouldn’t linger past the point where they would be “stale”.
In practice, this field is not used in exactly this manner. Routers today are fast and usually take far less than a second to forward a datagram; measuring the time that a datagram “lives” would be impractical. Instead, this field is used as a “maximum hop count” for the datagram. Each time a router processes a datagram, it reduces the value of the TTL field by one. If doing this results in the field being zero, the datagram is said to have expired. It is dropped, and usually an ICMPTime Exceeded message is sent to inform the originator of the message that this happened.
The TTL field is one of the primary mechanisms by which networks are protected from router loops (see the description of ICMP Time Exceeded messages for more on how TTL helps IP handle router loops.)

Type Of Service (TOS) Field

his one-byte field was originally intended to provide certain quality of service features for IP datagram delivery. It allowed IP datagrams to be tagged with information indicating not only their precedence, but the preferred manner in which they should be delivered. It was divided into a number of subfields, as shown in Table 57 (and Figure 86).
The lack of quality of service features has been considered a weakness of IP for a long time. But as we can see in Table 57, these features were built into IP from the start. What's going on here? The answer is that even though this field was defined in the standard back in the early 1980s, it was not widely used by hardware and software. For years, it was just passed around with all zeroes in the bits and mostly ignored.

Table 57: Original Definition Of IPv4 Type Of Service (TOS) Field
Subfield Name
Size (bytes)
Description
Precedence
3/8
(3 bits)


D
1/8
(1 bit)
Delay: Set to 0 to request “normal” delay in delivery; set to 1 if low delay delivery is requested.
T
1/8
(1 bit)
Throughput: Set to 0 to request “normal” delivery throughput; set to 1 if higher throughput delivery is requested.
R
1/8
(1 bit)
Reliability: Set to 0 to request “normal” reliability in delivery; set to 1 if higher reliability delivery is requested.
Reserved
2/8
(2 bits)
Reserved: Not used.

The IETF, seeing the field unused, attempted to revive its use. In 1998, RFC 2474 redefines the first six bits of the TOS field to support a technique called Differentiated Services (DS). Under DS, the values in the TOS field are calledcodepoints and are associated with different service levels. This starts to get rather complicated, so refer to RFC 2474 if you want all the details.
Understanding the IP datagram format is an important part of troubleshooting IP networks. Be sure to see the following topic on options for more information on how IP options are used in datagrams, and the topic on fragmenting for some more context on the use of fragmentation-related fields such as IdentificationFragment Offset, and More Fragments.

IP Datagram Encapsulation

In the chapter describing the OSI Reference Model, I looked at several ways that protocols at various layers in a networking protocol stack interact with each other. One of the most important concepts in inter-protocol operation is that ofencapsulation. Most data originates within the higher layers of the OSI model. The protocols at these layers pass the data down to lower layers for transmission, usually in the form of discrete messages. Upon receipt, each lower-level protocol takes the entire contents of the message received and encapsulates it into its own message format, adding a header and possibly a footer that contain important control information. Encapsulation is explained in general terms in a separate topic.
A good analogy for how encapsulation works is a comparison to sending a letter enclosed in an envelope. You might write a letter and put it in a white envelope with a name and address, but if you gave it to a courier for overnight delivery, they would take that envelope and put it in a larger delivery envelope. (I actually have written a complete description of this sort of analogy, if you are interested.)
Due to the prominence of TCP/IP, the Internet Protocol is one of the most important places where data encapsulation occurs on a modern network. Data is passed to IP typically from one of the two main transport layer protocols: TCP or UDP. This data is already in the form of a TCP or UDP message with TCP or UDP headers. This is then encapsulated into the body of an IP message, usually called an IP datagram or IP packet. Encapsulation and formatting of an IP datagram is also sometimes called packaging—again, the implied comparison to an envelope is obvious. The process is shown in Figure 85.

Figure 85: IP Datagram Encapsulation
This is an adaptation of Figure 15, the very similar drawing for the OSI Reference Model as a whole, showing specifically how data encapsulation is accomplished in TCP/IP. As you can see, an upper layer message is packaged into a TCP or UDP message. This then becomes the payload of an IP datagram, which is shown here simply with one header (things can get a bit more complex than this.) The IP datagram is then passed down to layer 2 where it is in turn encapsulated into some sort of LAN, WAN or WLAN frame, then converted to bits and transmitted at the physical layer.


If the message to be transmitted is too large for the size of the underlying network, it may first be fragmented. This is analogous to splitting up a large delivery into multiple smaller envelopes or boxes. In this case, each IP datagram carries only part of the higher-layer message. The receiving device must reassemble the message from the IP datagrams. So, a datagram doesn't always carry a full higher-layer message; it may hold only part of one.
The IP datagram is somewhat similar in concept to a frame used in Ethernet or another data link layer. The important difference, of course, is that IP datagrams are designed to facilitate transmission across an internetwork, while data link layer frames are used only for direct delivery within a physical network. The fields included in the IP header are used to manage internetwork datagram delivery. This includes key information for delivery such as the address of the destination device, identification of the type of frame, and control bits. The header follows a specific format described in the following topic.
After data is encapsulated into an IP datagram, it is passed down to the data link layer for transmission across the current “hop” of the internetwork. There, it is of course further encapsulated, IP header and all, into a data link layer frame such as an Ethernet frame. An IP datagram may be encapsulated into many such data link layer frames as it is routed across the internetwork; on each hop the IP datagram is removed from the data link layer frame and then repackaged into a new one for the next hop. The IP datagram, however, is not changed (except for some control fields) until it reaches its final destination.

C# Memory Model

The C# Memory Model in Theory and Practice

This is the first of a two-part series that will tell the long story of the C# memory model. The first part explains the guarantees the C# memory model makes and shows the code patterns that motivate the guarantees; the second part will detail how the guarantees are achieved on different hardware architectures in the Microsoft .NET Framework 4.5.
One source of complexity in multithreaded programming is that the compiler and the hardware can subtly transform a program’s memory operations in ways that don’t affect the single-threaded behavior, but might affect the multithreaded behavior. Consider the following method:
void Init() {
  _data = 42;
  _initialized = true;
}
If _data and _initialized are ordinary (that is, non-volatile) fields, the compiler and the processor are allowed to reorder the operations so that Init executes as if it were written like this:
void Init() {
  _initialized = true;
  _data = 42;
}
There are various optimizations in both compilers and processors that can result in this kind of reordering, as I’ll discuss in Part 2.
In a single-threaded program, the reordering of statements in Init makes no difference in the meaning of the program. As long as both _initialized and _data are updated before the method returns, the order of the assignments doesn’t matter. In a single-threaded program, there’s no second thread that could observe the state in between the updates.
In a multithreaded program, however, the order of the assignments may matter because another thread might read the fields while Init is in the middle of execution. Consequently, in the reordered version of Init, another thread may observe _initialized=true and _data=0.
The C# memory model is a set of rules that describes what kinds of memory-operation reordering are and are not allowed. All programs should be written against the guarantees defined in the specification.
However, even if the compiler and the processor are allowed to reorder memory operations, it doesn’t mean they always do so in practice. Many programs that contain a “bug” according to the abstract C# memory model will still execute correctly on particular hardware running a particular version of the .NET Framework. Notably, the x86 and x64 processors reorder operations only in certain narrow scenarios, and similarly the CLR just-in-time (JIT) compiler doesn’t perform many of the transformations it’s allowed to.
Although the abstract C# memory model is what you should have in mind when writing new code, it can be helpful to understand the actual implementation of the memory model on different architectures, in particular when trying to understand the behavior of existing code.

C# Memory Model According to ECMA-334

The authoritative definition of the C# memory model is in the Standard ECMA-334 C# Language Specification (bit.ly/MXMCrN). Let’s discuss the C# memory model as defined in the specification.
Memory Operation Reordering According to ECMA-334, when a thread reads a memory location in C# that was written to by a different thread, the reader might see a stale value. This problem is illustrated in Figure 1.
Figure 1 Code at Risk of Memory Operation Reordering
public class DataInit {
  private int _data = 0;
  private bool _initialized = false;
  void Init() {
    _data = 42;            // Write 1
    _initialized = true;   // Write 2
  }
  void Print() {
    if (_initialized)            // Read 1
      Console.WriteLine(_data);  // Read 2
    else
      Console.WriteLine("Not initialized");
  }
}
Suppose Init and Print are called in parallel (that is, on different threads) on a new instance of DataInit. If you examine the code of Init and Print, it may seem that Print can only output “42” or “Not initialized.” However, Print can also output “0.”
The C# memory model permits reordering of memory operations in a method, as long as the behavior of single-threaded execution doesn’t change. For example, the compiler and the processor are free to reorder the Init method operations as follows:
void Init() {
  _initialized = true;   // Write 2
  _data = 42;            // Write 1
}
This reordering wouldn’t change the behavior of the Init method in a single-threaded program. In a multithreaded program, however, another thread might read _initialized and _data fields after Init has modified one field but not the other, and then the reordering could change the behavior of the program. As a result, the Print method could end up outputting a “0.”
The reordering of Init isn’t the only possible source of trouble in this code sample. Even if the Init writes don’t end up reordered, the reads in the Print method could be transformed:
void Print() {
  int d = _data;     // Read 2
  if (_initialized)  // Read 1
    Console.WriteLine(d);
  else
    Console.WriteLine("Not initialized");
}
Just as with the reordering of writes, this transformation has no effect in a single-threaded program, but might change the behavior of a multithreaded program. And, just like the reordering of writes, the reordering of reads can also result in a 0 printed to the output.
In Part 2 of this article, you’ll see how and why these transformations take place in practice when I look at different hardware architectures in detail.
Volatile Fields The C# programming language provides volatile fields that constrain how memory operations can be reordered. The ECMA specification states that volatile fields provide acquire-­release semantics (bit.ly/NArSlt).
A read of a volatile field has acquire semantics, which means it can’t be reordered with subsequent operations. The volatile read forms a one-way fence: preceding operations can pass it, but subsequent operations can’t. Consider this example:
class AcquireSemanticsExample {
  int _a;
  volatile int _b;
  int _c;
  void Foo() {
    int a = _a; // Read 1
    int b = _b; // Read 2 (volatile)
    int c = _c; // Read 3
    ...
  }
}
Read 1 and Read 3 are non-volatile, while Read 2 is volatile. Read 2 can’t be reordered with Read 3, but it can be reordered with Read 1. Figure 2 shows the valid reorderings of the Foo body.
Figure 2 Valid Reordering of Reads in AcquireSemanticsExample
int a = _a; // Read 1
int b = _b; // Read 2 (volatile)
int c = _c; // Read 3
int b = _b; // Read 2 (volatile)
int a = _a; // Read 1
int c = _c; // Read 3
int b = _b; // Read 2 (volatile)
int c = _c; // Read 3
int a = _a; // Read 1
A write of a volatile field, on the other hand, has release semantics, and so it can’t be reordered with prior operations. A volatile write forms a one-way fence, as this example demonstrates:
class ReleaseSemanticsExample
{
  int _a;
  volatile int _b;
  int _c;
  void Foo()
  {
    _a = 1; // Write 1
    _b = 1; // Write 2 (volatile)
    _c = 1; // Write 3
    ...
  }
}
Write 1 and Write 3 are non-volatile, while Write 2 is volatile. Write 2 can’t be reordered with Write 1, but it can be reordered with Write 3. Figure 3 shows the valid reorderings of the Foo body.
Figure 3 Valid Reordering of Writes in ReleaseSemanticsExample
_a = 1; // Write 1
_b = 1; // Write 2 (volatile)
_c = 1; // Write 3
_a = 1; // Write 1
_c = 1; // Write 3
_b = 1; // Write 2 (volatile)
_c = 1; // Write 3
_a = 1; // Write 1
_b = 1; // Write 2 (volatile)
I’ll come back to the acquire-release semantics in the “Publication via Volatile Field” section later in this article.
Atomicity Another issue to be aware of is that in C#, values aren’t necessarily written atomically into memory. Consider this example:
class AtomicityExample {
  Guid _value;
  void SetValue(Guid value) { _value = value; }
  Guid GetValue() { return _value; }
}
If one thread repeatedly calls SetValue and another thread calls GetValue, the getter thread might observe a value that was never written by the setter thread. For example, if the setter thread alternately calls SetValue with Guid values (0,0,0,0) and (5,5,5,5), GetValue could observe (0,0,0,5) or (0,0,5,5) or (5,5,0,0), even though none of those values was ever assigned using SetValue.
The reason behind the “tearing” is that the assignment “_value = value” doesn’t execute atomically at the hardware level. Similarly, the read of _value also doesn’t execute atomically.
The C# ECMA specification guarantees that the following types will be written atomically: reference types, bool, char, byte, sbyte, short, ushort, uint, int and float. Values of other types—including user-defined value types—could be written into memory in multiple atomic writes. As a result, a reading thread could observe a torn value consisting of pieces of different values.
One caveat is that even the types that are normally read and written atomically (such as int) could be read or written non-atomically if the value is not correctly aligned in memory. Normally, C# will ensure that values are correctly aligned, but the user is able to override the alignment using the StructLayoutAttribute class (bit.ly/Tqa0MZ).
Non-Reordering Optimizations Some compiler optimizations may introduce or eliminate certain memory operations. For example, the compiler might replace repeated reads of a field with a single read. Similarly, if code reads a field and stores the value in a local variable and then repeatedly reads the variable, the compiler could choose to repeatedly read the field instead.
Because the ECMA C# spec doesn’t rule out the non-reordering optimizations, they’re presumably allowed. In fact, as I’ll discuss in Part 2, the JIT compiler does perform these types of optimizations.

Thread Communication Patterns

The purpose of a memory model is to enable thread communication. When one thread writes values to memory and another thread reads from memory, the memory model dictates what values the reading thread might see.
Locking Locking is typically the easiest way to share data among threads. If you use locks correctly, you basically don’t have to worry about any of the memory model messiness.
Whenever a thread acquires a lock, the CLR ensures that the thread will see all updates made by the thread that held the lock earlier. Let’s add locking to the example from the beginning of this article, as shown inFigure 4.
Figure 4 Thread Communication with Locking
public class Test {
  private int _a = 0;
  private int _b = 0;
  private object _lock = new object();
  void Set() {
    lock (_lock) {
      _a = 1;
      _b = 1;
    }
  }
  void Print() {
    lock (_lock) {
      int b = _b;
      int a = _a;
      Console.WriteLine("{0} {1}", a, b);
    }
  }
}
Adding a lock that Print and Set acquire provides a simple solution. Now, Set and Print execute atomically with respect to each other. The lock statement guarantees that the bodies of Print and Set will appear to execute in some sequential order, even if they’re called from multiple threads.
The diagram in Figure 5 shows one possible sequential order that could happen if Thread 1 calls Print three times, Thread 2 calls Set once and Thread 3 calls Print once.
Sequential Execution with Locking
Figure 5 Sequential Execution with Locking
When a locked block of code executes, it’s guaranteed to see all writes from blocks that precede the block in the sequential order of the lock. Also, it’s guaranteed not to see any of the writes from blocks that follow it in the sequential order of the lock.
In short, locks hide all of the unpredictability and complexity weirdness of the memory model: You don’t have to worry about the reordering of memory operations if you use locks correctly. However, note that the use of locking has to be correct. If only Print or Set uses the lock—or Print and Set acquire two different locks—memory operations can become reordered and the complexity of the memory model comes back.
Publication via Threading API Locking is a very general and powerful mechanism for sharing state among threads. Publication via threading API is another frequently used pattern of concurrent programming.
The easiest way to illustrate publication via threading API is by way of an example:
class Test2 {
  static int s_value;
  static void Run() {
    s_value = 42;
    Task t = Task.Factory.StartNew(() => {
      Console.WriteLine(s_value);
    });
    t.Wait();
  }
}
When you examine the preceding code sample, you’d probably expect “42” to be printed to the screen. And, in fact, your intuition would be correct. This code sample is guaranteed to print “42.”
It might be surprising that this case even needs to be mentioned, but in fact there are possible implementations of StartNew that would allow “0” to be printed instead of “42,” at least in theory. After all, there are two threads communicating via a non-volatile field, so memory operations can be reordered. The pattern is displayed in the diagram in Figure 6.
Two Threads Communicating via a Non-Volatile Field
Figure 6 Two Threads Communicating via a Non-Volatile Field
The StartNew implementation must ensure that the write to s_value on Thread 1 will not move after <start task t>, and the read from s_value on Thread 2 will not move before <task t starting>. And, in fact, the StartNew API really does guarantee this.
All other threading APIs in the .NET Framework, such as Thread.Start and ThreadPool.QueueUserWorkItem, also make a similar guarantee. In fact, nearly every threading API must have some barrier semantics in order to function correctly. These are almost never documented, but can usually be deduced simply by thinking about what the guarantees would have to be in order for the API to be useful.
Publication via Type Initialization Another way to safely publish a value to multiple threads is to write the value to a static field in a static initializer or a static constructor. Consider this example:
class Test3
{
  static int s_value = 42;
  static object s_obj = new object();
  static void PrintValue()
  {
    Console.WriteLine(s_value);
    Console.WriteLine(s_obj == null);
  }
}
If Test3.PrintValue is called from multiple threads concurrently, is it guaranteed that each PrintValue call will print “42” and “false”? Or, could one of the calls also print “0” or “true”? Just as in the previous case, you do get the behavior you’d expect: Each thread is guaranteed to print “42” and “false.”
The patterns discussed so far all behave as you’d expect. Now I’ll get to cases whose behavior may be surprising.
Publication via Volatile Field Many concurrent programs can be built using the three simple patterns discussed so far, used together with concurrency primitives in the .NET System.Threading and System.Collections.Concurrent namespaces.
The pattern I’m about to discuss is so important that the semantics of the volatile keyword were designed around it. In fact, the best way to remember the volatile keyword semantics is to remember this pattern, instead of trying to memorize the abstract rules explained earlier in this article.
Let’s start with the example code in Figure 7. The DataInit class in Figure 7 has two methods, Init and Print; both may be called from multiple threads. If no memory operations are reordered, Print can only print “Not initialized” or “42,” but there are two possible cases when Print could print a “0”:
  • Write 1 and Write 2 were reordered.
  • Read 1 and Read 2 were reordered.
Figure 7 Using the Volatile Keyword
public class DataInit {
  private int _data = 0;
  private volatile bool _initialized = false;
  void Init() {
    _data = 42;            // Write 1
    _initialized = true;   // Write 2
  }
  void Print() {
    if (_initialized) {          // Read 1
      Console.WriteLine(_data);  // Read 2
    }
    else {
      Console.WriteLine("Not initialized");
    }
  }
}
If _initialized were not marked as volatile, both reorderings would be permitted. However, when _initialized is marked as volatile, neither reordering is allowed! In the case of writes, you have an ordinary write followed by a volatile write, and a volatile write can’t be reordered with a prior memory operation. In the case of the reads, you have a volatile read followed by an ordinary read, and a volatile read can’t be reordered with a subsequent memory operation.
So, Print will never print “0,” even if called concurrently with Init on a new instance of DataInit.
Note that if the _data field is volatile but _initialized is not, both reorderings would be permitted. As a result, remembering this example is a good way to remember the volatile semantics.
Lazy Initialization One common variant of publication via volatile field is lazy initialization. The example inFigure 8 illustrates lazy initialization.
Figure 8 Lazy Initialization
class BoxedInt
{
  public int Value { get; set; }
}
class LazyInit
{
  volatile BoxedInt _box;
  public int LazyGet()
  {
    var b = _box;  // Read 1
    if (b == null)
    {
      lock(this)
      {
        b = new BoxedInt();
        b.Value = 42; // Write 1
        _box = b;     // Write 2
      }
    }
    return b.Value; // Read 2
  }
}
In this example, LazyGet is always guaranteed to return “42.” However, if the _box field were not volatile, LazyGet would be allowed to return “0” for two reasons: the reads could get reordered, or the writes could get reordered.
To further emphasize the point, consider this class:
class BoxedInt2
{
  public readonly int _value = 42;
  void PrintValue()
  {
    Console.WriteLine(_value);
  }
}
Now, it’s possible—at least in theory—that PrintValue will print “0” due to a memory-model issue. Here’s a usage example of BoxedInt that allows it:
class Tester
{
  BoxedInt2 _box = null;
  public void Set() {
    _box = new BoxedInt2();
  }
  public void Print() {
    var b = _box;
    if (b != null) b.PrintValue();
  }
}
Because the BoxedInt instance was incorrectly published (through a non-volatile field, _box), the thread that calls Print may observe a partially constructed object! Again, making the _box field volatile would fix the issue.
Interlocked Operations and Memory Barriers Interlocked operations are atomic operations that can be used at times to reduce locking in a multithreaded program. Consider this simple thread-safe counter class:
class Counter
{
  private int _value = 0;
  private object _lock = new object();
  public int Increment()
  {
    lock (_lock)
    {
      _value++;
      return _value;
    }
  }
}
Using Interlocked.Increment, you can rewrite the program like this:
class Counter
{
  private int _value = 0;
  public int Increment()
  {
    return Interlocked.Increment(ref _value);
  }
}
As rewritten with Interlocked.Increment, the method should execute faster, at least on some architectures. In addition to the increment operations, the Interlocked class (bit.ly/RksCMF) exposes methods for various atomic operations: adding a value, conditionally replacing a value, replacing a value and returning the original value, and so forth.
All Interlocked methods have one very interesting property: They can’t be reordered with other memory operations. So no memory operation, whether before or after an Interlocked operation, can pass an Interlocked operation.
An operation that’s closely related to Interlocked methods is Thread.MemoryBarrier, which can be thought of as a dummy Interlocked operation. Just like an Interlocked method, Thread.Memory­Barrier can’t be reordered with any prior or subsequent memory operations. Unlike an Interlocked method, though, Thread.MemoryBarrier has no side effect; it simply constrains memory reorderings.
Polling Loop Polling loop is a pattern that’s generally not recommended but—somewhat unfortunately—frequently used in practice. Figure 9 shows a broken polling loop.
Figure 9 Broken Polling Loop
class PollingLoopExample
{
  private bool _loop = true;
  public static void Main()
  {
    PollingLoopExample test1 = new PollingLoopExample();
    // Set _loop to false on another thread
    new Thread(() => { test1._loop = false;}).Start();
    // Poll the _loop field until it is set to false
    while (test1._loop) ;
    // The previous loop may never terminate
  }
}
In this example, the main thread loops, polling a particular non-volatile field. A helper thread sets the field in the meantime, but the main thread may never see the updated value.
Now, what if the _loop field was marked volatile? Would that fix the program? The general expert consensus seems to be that the compiler isn’t allowed to hoist a volatile field read out of a loop, but it’s debatable whether the ECMA C# specification makes this guarantee.
On one hand, the specification states only that volatile fields obey the acquire-release semantics, which doesn’t seem sufficient to prevent hoisting of a volatile field. On the other hand, the example code in the specification does in fact poll a volatile field, implying that the volatile field read can’t be hoisted out of the loop.
On x86 and x64 architectures, PollingLoopExample.Main will typically hang. The JIT compiler will read test1._loop field just once, save the value in a register, and then loop until the register value changes, which will obviously never happen.
If the loop body contains some statements, however, the JIT compiler will probably need the register for some other purpose, so each iteration may end up rereading test1._loop. As a result, you may end up seeing loops in existing programs that poll a non-­volatile field and yet happen to work.
Concurrency Primitives Much concurrent code can benefit from high-level concurrency primitives that became available in the .NET Framework 4. Figure 10 lists some of the .NET concurrency primitives.
Figure 10 Concurrency Primitives in the .NET Framework 4
TypeDescription
Lazy<>Lazily initialized values
LazyInitializer
BlockingCollection<>Thread-safe collections
ConcurrentBag<>
ConcurrentDictionary<,>
ConcurrentQueue<>
ConcurrentStack<>
AutoResetEventPrimitives to coordinate execution of different threads
Barrier
CountdownEvent
ManualResetEventSlim
Monitor
SemaphoreSlim
ThreadLocal<>Container that holds a separate value for every thread
By using these primitives, you can often avoid low-level code that depends on the memory model in intricate ways (via volatile and the like).

Coming Up

So far, I’ve described the C# memory model as defined in the ECMA C# specification, and discussed the most important patterns of thread communication that define the memory model.
The second part of this article will explain how the memory model is actually implemented on different architectures, which is helpful for understanding the behavior of programs in the real world.

Best Practices

  • All code you write should rely only on the guarantees made by the ECMA C# specification, and not on any of the implementation details explained in this article.
  • Avoid unnecessary use of volatile fields. Most of the time, locks or concurrent collections (System.Collections.Concurrent.*) are more appropriate for exchanging data between threads. In some cases, volatile fields can be used to optimize concurrent code, but you should use performance measurements to validate that the benefit outweighs the extra complexity.
  • Instead of implementing the lazy initialization pattern yourself using a volatile field, use the System.Lazy<T> and System.Threading.LazyInitializer types.
  • Avoid polling loops. Often, you can use a BlockingCollection<T>, Monitor.Wait/Pulse, events or asynchronous programming instead of a polling loop.
  • Whenever possible, use the standard .NET concurrency primitives instead of implementing equivalent functionality yourself.


The C# Memory Model in Theory and Practice, Part 2


This is the second article in a two-part series that discusses the C# memory model. As explained in the first part in the December issue of MSDN Magazine (msdn.microsoft.com/magazine/jj863136), the compiler and the hardware may subtly transform the memory operations of a program in ways that don’t affect single-threaded behavior, but can impact multi-threaded behavior. As an example, consider this method:
void Init() {
  _data = 42;
  _initialized = true;
}
If _data and _initialized are ordinary (that is, non-volatile) fields, the compiler and the processor are allowed to reorder the operations so that Init executes as if it were written like this:
void Init() {
  _initialized = true;
  _data = 42;
}
In the previous article, I described the abstract C# memory model. In this article, I’ll explain how the C# memory model is actually implemented on different architectures supported by the Microsoft .NET Framework 4.5.

Compiler Optimizations

As mentioned in the first article, the compiler might optimize the code in a way that reorders memory operations. In the .NET Framework 4.5, the csc.exe compiler that compiles C# to IL doesn’t do many optimizations, so it won’t reorder memory operations. However, the just-in-time (JIT) compiler that converts IL to machine code will, in fact, perform some optimizations that reorder memory operations, as I’ll discuss.
Loop Read Hoisting Consider the polling loop pattern:
class Test
{
  private bool _flag = true;
  public void Run()
  {
    // Set _flag to false on another thread
    new Thread(() => { _flag = false; }).Start();
    // Poll the _flag field until it is set to false
    while (_flag) ;
    // The loop might never terminate!
  }
}
In this case, the .NET 4.5 JIT compiler might rewrite the loop like this:
if (_flag) { while (true); }
In the single-threaded case, this transformation is entirely legal and, in general, hoisting a read out of a loop is an excellent optimization. However, if the _flag is set to false on another thread, the optimization can cause a hang.
Note that if the _flag field were volatile, the JIT compiler would not hoist the read out of the loop. (See the “Polling Loop” section in the December article for a more detailed explanation of this pattern.)
Read Elimination Another compiler optimization that can cause errors in multi-threaded code is illustrated in this sample:
class Test
{
  private int _A, _B;
  public void Foo()
  {
    int a = _A;
    int b = _B;
    ...
  }
}
The class contains two non-volatile fields, _A and _B. Method Foo first reads field _A and then field _B. However, because the fields are non-volatile, the compiler is free to reorder the two reads. So, if the correctness of the algorithm depends on the order of the reads, the program contains a bug.
It’s hard to imagine what the compiler would gain by switching the order of the reads. Given the way Foo is written, the compiler probably wouldn’t swap the order of the reads.
However, the reordering does happen if I add another innocuous statement at the top of the Foo method:
public bool Foo()
{
  if (_B == -1) throw new Exception(); // Extra read
  int a = _A;
  int b = _B;
  return a > b;
}
On the first line of the Foo method, the compiler loads the value of _B into a register. Then, the second load of _B simply uses the value that’s already in the register instead of issuing a real load instruction.
Effectively, the compiler rewrites the Foo method as follows:
public bool Foo()
{
  int b = _B;
  if (b == -1) throw new Exception(); // Extra read
  int a = _A;
  return a > b;
}
Although this code sample gives a rough approximation of how the compiler optimizes the code, it’s also instructive to look at the disassembly of the code:
if (_B == -1) throw new Exception();
  push        eax
  mov         edx,dword ptr [ecx+8]
  // Load field _B into EDX register
  cmp         edx,0FFFFFFFFh
  je          00000016
int a = _A;
  mov         eax,dword ptr [ecx+4]
  // Load field _A into EAX register
return a > b;
  cmp         eax,edx
  // Compare registers EAX and EDX
...
Even if you don’t know assembly, what’s happening here is pretty easy to understand. As a part of evaluating the condition _B == -1, the compiler loads the _B field into the EDX register. Later, when field _B is read again, the compiler simply reuses the value it already has in EDX instead of issuing a real memory read. Consequently, the reads of _A and _B get reordered.
In this case, the correct solution is to mark field _A as volatile. If that’s done, the compiler shouldn’t reorder the reads of _A and _B, because the load of _A has load-acquire semantics. However, I should  point out that the .NET Framework, through version 4, doesn’t handle this case correctly and, in fact, marking the _A field as volatile will not prevent the read reordering. This issue has been fixed in the .NET Framework version 4.5.
Read Introduction As I just explained, the compiler sometimes fuses multiple reads into one. The compiler can also split a single read into multiple reads. In the .NET Framework 4.5, read introduction is much less common than read elimination and occurs only in very rare, specific circumstances. However, it does sometimes happen.
To understand read introduction, consider the following example:
public class ReadIntro {
  private Object _obj = new Object();
  void PrintObj() {
    Object obj = _obj;
    if (obj != null) {
      Console.WriteLine(obj.ToString());
    // May throw a NullReferenceException
    }
  }
  void Uninitialize() {
    _obj = null;
  }
}
If you examine the PrintObj method, it looks like the obj value will never be null in the obj.ToString expression. However, that line of code could in fact throw a NullReferenceException. The CLR JIT might compile the PrintObj method as if it were written like this:
void PrintObj() {
  if (_obj != null) {
    Console.WriteLine(_obj.ToString());
  }
}
Because the read of the _obj field has been split into two reads of the field, the ToString method may now be called on a null target.
Note that you won’t be able to reproduce the NullReferenceException using this code sample in the .NET Framework 4.5 on x86-x64. Read introduction is very difficult to reproduce in the .NET Framework 4.5, but it does nevertheless occur in certain special circumstances.

C# Memory Model Implementation on the x86-x64

As the x86 and x64 have the same behavior with respect to the memory model, I’ll consider both processor variants together.
Unlike some architectures, the x86-x64 processor provides fairly strong ordering guarantees on memory operations. In fact, the JIT compiler doesn’t need to use any special instructions on the x86-x64 to achieve volatile semantics; ordinary memory operations already provide those semantics. Even so, there are still specific cases when the x86-x64 processor does reorder memory operations.
x86-x64 Memory Reordering Even though the x86-x64 processor provides fairly strong ordering guarantees, a particular kind of hardware reordering still happens.
The x86-x64 processor will not reorder two writes, nor will it reorder two reads. However, the one (and only) possible reordering effect is that when a processor writes a value, that value will not be made immediately available to other processors. Figure 1 shows an example that demonstrates this behavior.
Figure 1 StoreBufferExample
class StoreBufferExample
{
  // On x86 .NET Framework 4.5, it makes no difference
  // whether these fields are volatile or not
  volatile int A = 0;
  volatile int B = 0;
  volatile bool A_Won = false;
  volatile bool B_Won = false;
  public void ThreadA()
  {
    A = true;
    if (!B) A_Won = true;
  }
  public void ThreadB()
  {
    B = true;
    if (!A) B_Won = true;
  }
}
Consider the case when methods ThreadA and ThreadB are called from different threads on a new instance of StoreBufferExample, as shown in Figure 2. If you think about the possible outcomes of the program in Figure 2, three cases seem to be possible:
  1. Thread 1 completes before Thread 2 starts. The outcome is A_Won=true, B_Won=false.
  2. Thread 2 completes before Thread 1 starts. The outcome is A_Won=false, B_Won=true.
  3. The threads interleave. The outcome is A_Won=false, B_Won=false.
Calling ThreadA and ThreadB Methods from Different Threads
Figure 2 Calling ThreadA and ThreadB Methods from Different Threads
But, surprisingly, there’s a fourth case: It’s possible that both the A_Won and B_Won fields will be true after this code has finished! Because of the store buffer, stores can get “delayed,” and therefore end up reordered with a subsequent load. Even though this outcome is not consistent with any interleaving of Thread 1 and Thread 2 executions, it can still happen.
This example is interesting because we have a processor (the x86-x64) with relatively strong ordering, and all fields are volatile—and we still observe a reordering of memory operations. Even though the write to A is volatile and the read from A_Won is also volatile, the fences are both one-directional, and in fact allow this reordering. So, the ThreadA method may effectively execute as if it were written like this:
public void ThreadA()
{
  bool tmp = B;
  A = true;
  if (!tmp) A_Won = 1;
}
One possible fix is to insert a memory barrier into both ThreadA and ThreadB. The updated ThreadA method would look like this:
public void ThreadA()
{
  A = true;
  Thread.MemoryBarrier();
  if (!B) aWon = 1;
}
The CLR JIT will insert a “lock or” instruction in place of the memory barrier. A locked x86 instruction has the side effect of flushing the store buffer:
mov         byte ptr [ecx+4],1
lock or     dword ptr [esp],0
cmp         byte ptr [ecx+5],0
jne         00000013
mov         byte ptr [ecx+6],1
ret
As an interesting side note, the Java programming language takes a different approach. The Java memory model has a slightly stronger definition of “volatile” that doesn’t permit store-load reordering, so a Java compiler on the x86 will typically emit a locked instruction after a volatile write.
x86-x64 Remarks The x86 processor has a fairly strong memory model, and the only source of reordering at the hardware level is the store buffer. The store buffer can cause a write to get reordered with a subsequent read (store-load reordering).
Also, certain compiler optimizations can result in reordering of memory operations. Notably, if several reads access the same memory location, the compiler might choose to perform the read only once and keep the value in a register for subsequent reads.
One interesting piece of trivia is that the C# volatile semantics closely match the hardware reordering guarantees made by x86-x64 hardware. As a result, reads and writes of volatile fields require no special instructions on the x86: Ordinary reads and writes (for example, using the MOV instruction) are sufficient. Of course, your code shouldn’t depend on these implementation details because they vary among hardware architectures and possibly .NET versions.

C# Memory Model Implementation on the Itanium Architecture

The Itanium hardware architecture has a memory model weaker than that of the x86-x64. Itanium was supported by the .NET Framework until version 4.
Even though Itanium is no longer supported in the .NET Framework 4.5, understanding the Itanium memory model is useful when you read older articles on the .NET memory model and have to maintain code that incorporated recommendations from those articles.
Itanium Reordering Itanium has a different instruction set than the x86-x64, and memory model concepts show up in the instruction set. Itanium distinguishes between an ordinary load (LD) and load-acquire (LD.ACQ), and an ordinary store (ST) and store-release (ST.REL).
Ordinary loads and stores can be freely reordered by the hardware, as long as the single-threaded behavior doesn’t change. For example, look at this code:
class ReorderingExample
{
  int _a = 0, _b = 0;
  void PrintAB()
  {
    int a = _a;
    int b = _b;
    Console.WriteLine("A:{0} B:{1}", a, b);
  }
  ...
}
Consider two reads of _a and _b in the PrintAB method. Because the reads access an ordinary, non-volatile field, the compiler will use ordinary LD (not LD.ACQ) to implement the reads. Consequently, the two reads might be effectively reordered in the hardware, so that PrintAB behaves as if it were written like this:
void PrintAB()
{
  int b = _b;
  int a = _a;
  Console.WriteLine("A:{0} B:{1}", a, b);
}
In practice, whether the reordering happens or not depends on a variety of unpredictable factors—what’s in the processor cache, how busy the processor pipeline is and so forth. However, the processor will not reorder two reads if they’re related via data dependency. Data dependency between two reads occurs when the value returned by a memory read determines the location of the read by a subsequent read.
This example illustrates data dependency:
class Counter { public int _value; }
class Test
{
  private Counter _counter = new Counter();
  void Do()
  {
    Counter c = _counter; // Read 1
    int value = c._value; // Read 2
  }
}
In the Do method, Itanium will never reorder Read 1 and Read 2, even though Read 1 is an ordinary load and not load-acquire. It might seem obvious that these two reads can’t be reordered: The first read determines which memory location the second read should access! However, some processors—other than Itanium—may in fact reorder the reads. The processor might guess on the value that Read 1 will return and perform Read 2 speculatively, even before Read 1 has completed. But, again, Itanium will not do that.
I’ll get back to the data dependency in Itanium discussion in a bit, and its relevance to the C# memory model will become clearer.
Also, itanium will not reorder two ordinary reads if they’re related via control dependency. Control dependency occurs when the value returned by a read determines whether a subsequent instruction will execute.
So, in this example, the reads of _initialized and _data are related via control dependency:
void Print() {
  if (_initialized)            // Read 1
    Console.WriteLine(_data);  // Read 2
  else
    Console.WriteLine("Not initialized");
}
Even if _initialized and _data are ordinary (non-volatile) reads, the Itanium processor will not reorder them. Note that the JIT compiler is still free to reorder the two reads, and in some cases will.
Also, it’s worth pointing out that, like the x86-x64 processor, Itanium also uses a store buffer, so the StoreBufferExample shown in Figure 1 will exhibit the same kind of reorderings on Itanium as it did on the x86-x64. An interesting piece of trivia is that if you use LD.ACQ for all reads and ST.REL for all writes on Itanium, you basically get the x86-x64 memory model, where the store buffer is the only source of reordering.
Compiler Behavior on Itanium The CLR JIT compiler has one surprising behavior on Itanium: all writes are emitted as ST.REL, and not ST. Consequently, a volatile write and a non-volatile write will typically emit the same instruction on Itanium. However, an ordinary read will be emitted as LD; only reads from volatile fields are emitted as LD.ACQ.
This behavior might come as a surprise because the compiler is certainly not required to emit ST.REL for non-volatile writes. As far as the European Computer Manufacturers Association (ECMA) C# specification is concerned, the compiler could emit ordinary ST instructions. Emitting ST.REL is just something extra that the compiler chooses to do, in order to ensure that a particular common (but in theory incorrect) pattern will work as expected.
It can be difficult to imagine what that important pattern might be where ST.REL must be used for writes, but LD is sufficient for reads. In the PrintAB example presented earlier in this section, constraining just the writes wouldn’t help, because reads could still be reordered.
There’s one very important scenario in which using ST.REL with ordinary LD is sufficient: when the loads themselves are ordered using data dependency. This pattern comes up in lazy initialization, which is an extremely important pattern. Figure 3 shows an example of lazy initialization.
Figure 3 Lazy Initialization
// Warning: Might not work on future architectures and .NET versions;
// do not use
class LazyExample
{
  private BoxedInt _boxedInt;
  int GetInt()
  {
    BoxedInt b = _boxedInt; // Read 1
    if (b == null)
    {
      lock(this)
      {
        if (_boxedInt == null)
        {
          b = new BoxedInt();
          b._value = 42;  // Write 1
          _boxedInt = b; // Write 2
        }
      }
    }
    int value = b._value; // Read 2
    return value;
  }
}
In order for this bit of code to always return 42—even if GetInt is called from multiple threads concurrently—Read 1 must not be reordered with Read 2, and Write 1 must not be reordered with Write 2. The reads will not be reordered by the Itanium processor because they’re related via data dependency. And, the writes will not be reordered because the CLR JIT emits them as ST.REL.
Note that if the _boxedInt field were volatile, the code would be correct according to the ECMA C# spec. That’s the best kind of correct, and arguably the only real kind of correct. However, even if _boxed is not volatile, the current version of the compiler will ensure that the code still works on Itanium in practice.
Of course, loop read hoisting, read elimination and read introduction may be performed by the CLR JIT on Itanium, just as they are on x86-x64.
Itanium Remarks The reason Itanium is an interesting part of the story is that it was the first architecture with a weak memory model that ran the .NET Framework.
As a result, in a number of articles about the C# memory model and the volatile keyword and C#, the authors generally had Itanium in mind. After all, until the .NET Framework 4.5, Itanium was the only architecture other than the x86-x64 that ran the .NET Framework.
Consequently, the author might say something like, “In the .NET 2.0 memory model, all writes are volatile—even those to non-volatile fields.” What the author means is that on Itanium, CLR will emit all writes as ST.REL. This behavior isn’t guaranteed by the ECMA C# spec, and, consequently, might not hold in future versions of the .NET Framework and on future architectures (and, in fact, does not hold in the .NET Framework 4.5 on ARM).
Similarly, some folks would argue that lazy initialization is correct in the .NET Framework even if the holding field is non-­volatile, while others would say that the field must be volatile.
And of course, developers wrote code against these (sometimes contradictory) assumptions. So, understanding the Itanium part of the story can be helpful when trying to make sense of concurrent code written by someone else, reading older articles or even just talking to other developers.

C# Memory Model Implementation on ARM

The ARM architecture is the most recent addition to the list of architectures supported by the .NET Framework. Like Itanium, ARM has a weaker memory model than the x86-x64.
ARM Reordering Just like Itanium, ARM is allowed to freely reorder ordinary reads and writes. However, the solution that ARM provides to tame the movement of reads and writes is somewhat different from that of Itanium. ARM exposes a single instruction—DMB—that acts as a full memory barrier. No memory operation can pass over DMB in either direction.
In addition to the constraints imposed by the DMB instruction, ARM also respects data dependency, but doesn’t respect control dependency. See the “Itanium Reordering” section earlier in this article for explanations of data and control dependencies.
Compiler Behavior on ARM The DMB instruction is used to implement the volatile semantics in C#. On ARM, the CLR JIT implements a read from a volatile field using an ordinary read (such as LDR) followed by the DMB instruction. Because the DMB instruction will prevent the volatile read from getting reordered with any subsequent operations, this solution correctly implements the acquire semantics.
A write to a volatile field is implemented using the DMB instruction followed by an ordinary write (such as STR). Because the DMB instruction prevents the volatile write from getting reordered with any prior operations, this solution correctly implements the release semantics.
Just as with the Itanium processor, it would be nice to go beyond the ECMA C# spec and keep the lazy initialization pattern working, because a lot of existing code depends on it. However, making all writes effectively volatile is not a good solution on ARM because the DBM instruction is fairly costly.
In the .NET Framework 4.5, the CLR JIT uses a slightly different trick to get lazy initialization working. The following are treated as “release” barriers:
  1. Writes to reference-type fields on the garbage collector (GC) heap
  2. Writes to reference-type static fields
As a result, any write that might publish an object is treated as a release barrier.
This is the relevant part of LazyExample (recall that none of the fields are volatile):
b = new BoxedInt();
b._value = 42;  // Write 1
// DMB will be emitted here
_boxedInt = b; // Write 2
Because the CLR JIT emits the DMB instructions prior to the publication of the object into the _boxedInt field, Write 1 and Write 2 will not be reordered. And because ARM respects data dependence, the reads in the lazy initialization pattern will not be reordered either, and the code will work correctly on ARM.
So, the CLR JIT makes an extra effort (beyond what’s mandated in the ECMA C# spec) to keep the most common variant of incorrect lazy initialization working on ARM.
As a final comment on ARM, note that—as on x86-x64 and Itanium—loop read hoisting, read elimination and read introduction are all legitimate optimizations as far as the CLR JIT is concerned.

Example: Lazy Initialization

It can be instructive to look at a few different variants of the lazy initialization pattern and think about how they’ll behave on different architectures.
Correct Implementation The implementation of lazy initialization in Figure 4is correct according to the C# memory model as defined by the ECMA C# spec, and so it’s guaranteed to work on all architectures supported by current and future versions of the .NET Framework.
Figure 4 A Correct Implementation of Lazy Initialization
class BoxedInt
{
  public int _value;
  public BoxedInt() { }
  public BoxedInt(int value) { _value = value; }
}
class LazyExample
{
  private volatile BoxedInt _boxedInt;
  int GetInt()
  {
    BoxedInt b = _boxedInt;
    if (b == null)
    {
      b = new BoxedInt(42);
      _boxedInt = b;
    }
    return b._value;
  }
}
Note that even though the code sample is correct, in practice it’s still preferable to use the Lazy<T> or the LazyInitializer type.
Incorrect Implementation No. 1Figure 5 shows an implementation that isn’t correct according to the C# memory model. In spite of this, the implementation will probably work on the x86-x64, Itanium and ARM in the .NET Framework. This version of the code is not correct. Because _boxedInt isn’t volatile, a C# compiler is permitted to reorder Read 1 with Read 2, or Write 1 with Write 2. Either reordering would potentially result in 0 returned from GetInt.
Figure 5 An Incorrect Implementation of Lazy Initialization
// Warning: Bad code
class LazyExample
{
  private BoxedInt _boxedInt; // Note: This field is not volatile
  int GetInt()
  {
    BoxedInt b = _boxedInt; // Read 1
    if (b == null)
    {
      b = new BoxedInt(42); // Write 1 (inside constructor)
      _boxedInt = b;        // Write 2
    }
    return b._value;        // Read 2
  }
}
However, this code will behave correctly (that is, always return 42) on all architectures in the .NET Framework versions 4 and 4.5:
  • x86-x64:
    • Writes and reads will not be reordered. There is no store-load pattern in the code, and also no reason the compiler would cache values in registers.
  • Itanium:
    • Writes will not be reordered because they are ST.REL.
    • Reads will not be reordered due to data dependency.
  • ARM:
    • Writes will not be reordered because DMB is emitted before “_boxedInt = b.”
    • Reads will not be reordered due to data dependency.
Of course, you should use this information only to try to understand the behavior of existing code. Do not use this pattern when writing new code.
Incorrect Implementation No. 2 The incorrect implementation in Figure 6 may fail on both ARM and Itanium.
Figure 6 A Second Incorrect Implementation of Lazy Initialization
// Warning: Bad code
class LazyExample
{
  private int _value;
  private bool _initialized;
  int GetInt()
  {
    if (!_initialized) // Read 1
    {
      _value = 42;
      _initialized = true;
    }
    return _value;     // Read 2
  }
}
This version of lazy initialization uses two separate fields to track the data (_value) and whether the field is initialized (_initialized). As a result, the two reads—Read 1 and Read 2—are no longer related via data dependency. Additionally, on ARM, the writes might also get reordered, for the same reasons as in the next incorrect implementation (No. 3).
As a result, this version may fail and return 0 on ARM and Itanium in practice. Of course, GetInt is allowed to return 0 on x86-x64 (and also as a result of JIT optimizations), but that behavior doesn’t seem to happen in the .NET Framework 4.5.
Incorrect Implementation No. 3 Finally, it’s possible to get the example to fail even on x86-x64. I just have to add one innocuous-looking read, as shown in Figure 7.
Figure 7 A Third Incorrect Implementation of Lazy Initialization
// WARNING: Bad code
class LazyExample
{
  private int _value;
  private bool _initialized;
  int GetInt()
  {
    if (_value < 0) throw new Exception(); // Note: extra reads to get _value
                                         // pre-loaded into a register
    if (!_initialized)      // Read 1
    {
      _value = 42;
      _initialized = true;
      return _value;
    }
    return _value;          // Read 2
  }
}
The extra read that checks whether _value < 0 can now cause the compiler to cache the value in register. As a result, Read 2 will get serviced from a register, and so it gets effectively reordered with Read 1. Consequently, this version of GetInt may in practice return 0 even on x86-x64.

Wrapping Up

When writing new multi-threaded code, it’s generally a good idea to avoid the complexity of the C# memory model altogether by using high-level concurrency primitives like locks, concurrent collections, tasks, and parallel loops. When writing CPU-intensive code, it sometimes makes sense to use volatile fields, as long as you only rely on the ECMA C# specification guarantees and not on architecture-specific implementation details.