C# - the language Archives - Anuj Varma, Hands-On Technology Architect, Clean Air Activist https://www.anujvarma.com/category/technology/languages-platforms-object-oriented-observations/csharp/ Production Grade Technical Solutions | Data Encryption and Public Cloud Expert Wed, 21 Feb 2024 15:27:47 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://www.anujvarma.com/wp-content/uploads/anujtech.png C# - the language Archives - Anuj Varma, Hands-On Technology Architect, Clean Air Activist https://www.anujvarma.com/category/technology/languages-platforms-object-oriented-observations/csharp/ 32 32 Task Async Await https://www.anujvarma.com/task-async-await/ https://www.anujvarma.com/task-async-await/#respond Mon, 16 Oct 2017 20:54:00 +0000 http://www.anujvarma.com/?p=5413 Long Running Task that returns an int call result  = await The method containing the Task has to be marked async The method running the long running task also needs […]

The post Task Async Await appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
  • Long Running Task that returns an int
  • call result  = await
  • The method containing the Task has to be marked async
  • The method running the long running task also needs to be marked async? Because it contains await
  • public async Task MyMethodAsync()
    {
        Task<int> longRunningTask = LongRunningOperationAsync();
        // independent work which doesn't need the result of LongRunningOperationAsync can be done here
    
        //and now we call await on the task 
        int result = await longRunningTask;
        //use the result 
        Console.WriteLine(result);
    }
    
    public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation 
    {
        await Task.Delay(1000); // 1 second delay
        return 1;
    }/

    The post Task Async Await appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    https://www.anujvarma.com/task-async-await/feed/ 0
    Books on Algorithms https://www.anujvarma.com/books-on-algorithms/ https://www.anujvarma.com/books-on-algorithms/#comments Wed, 14 Jun 2017 22:17:51 +0000 http://www.anujvarma.com/?p=4769 Also see my – Problem Books for Pure Math, Physics and Mathematical Physics If you are looking for a recap of computer science algorithmic concepts either for fun or for […]

    The post Books on Algorithms appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    Also see my – Problem Books for Pure Math, Physics and Mathematical Physics

    If you are looking for a recap of computer science algorithmic concepts either for fun or for an upcoming programming interview, look no further than these books.

    • The first one – Data Structures and Algorithms Made Easy –  A great reference and easy to read. This one is a little time consuming, which is why I listed the second option below.
    • The second one – Beginning Algorithms (Wrox Book)is a little more concise and more basic.  Maybe not for the google interview, but for most mid-level tech interviews, I prefer the Wrox book as a refresher.
    • Python Algorithms – by  Hetland. A Press publication. Don’t be put off if python isn’t your first language. The explanation of algorithms in general, itself makes this worth the money.

    Summary

    Do you have a favorite algorithms book? Please share in the comments.

    The post Books on Algorithms appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    https://www.anujvarma.com/books-on-algorithms/feed/ 1
    Recursion versus Iteration ( Looping ) https://www.anujvarma.com/recursion-versus-looping/ https://www.anujvarma.com/recursion-versus-looping/#respond Mon, 13 Jun 2016 18:39:35 +0000 http://www.anujvarma.com/?p=4233 Overview In general, whatever problem you can solve with Recursion can also be solved with Looping (iteration). It turns out, that for most use cases, Iteration (looping) performs better than […]

    The post Recursion versus Iteration ( Looping ) appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    Overview

    In general, whatever problem you can solve with Recursion can also be solved with Looping (iteration).

    It turns out, that for most use cases, Iteration (looping) performs better than Recursion

    The problem with recursion, is that small results need to be computed many times. This makes it somewhat inefficient.

    Looping can accomplish the same result – without being computationally expensive.

    fibonacci

    Summary

    As you can see, recursion is almost 10,000 times as expensive as Looping. It gets more expensive as the computation increases (as N increases).

    Here is the full source code, in C#

    Example – Fibonacci  – Using Recursion

     

          private static int RecurseFibonacci(int f)
    {
    if (f <= 1)
    return 1;
    else
    {
    return RecurseFibonacci(f  1) + RecurseFibonacci(f  2);
    }
    }

    Example – Fibonacci  – Using Looping

    static int LoopFibonacci(int n)
    {
    int prev = 1; int first = 1; int next = 1; 

    if (n <= 1)
    return 1;
    else
    {
    for(int k=2; k<=n; k++)
    {
    next = first + prev;
    first = prev;
    prev = next;
    } 

    return prev;
    }
    }

       static void Main(string[] args)
    { 

    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();
    int result1  = LoopFibonacci(f);
    stopwatch.Stop(); 

    // Write hours, minutes and seconds.
                Console.WriteLine(” Computing Fibonacci for N = ” + f);
    Console.WriteLine(“Fibonacci Result = ” + result1 + ” Loop Time:” + stopwatch.Elapsed.TotalMilliseconds + ” ms”); 

    stopwatch.Start();
    int result2 = RecurseFibonacci(f);
    stopwatch.Stop();
    // Write hours, minutes and seconds.
                Console.WriteLine(“Fibonacci Result = ” + result2 + ” Recursion Time: ” + stopwatch.Elapsed.TotalMilliseconds + ” ms”); 

    }

    The post Recursion versus Iteration ( Looping ) appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    https://www.anujvarma.com/recursion-versus-looping/feed/ 0
    Binary tree (count nodes) interview question https://www.anujvarma.com/binary-tree-count-nodes-interview-question/ https://www.anujvarma.com/binary-tree-count-nodes-interview-question/#respond Tue, 28 Apr 2015 21:43:32 +0000 http://www.anujvarma.com/?p=3037 Given a LEFT and a RIGHT property that returns the underlying LEFT tree and the underlying RIGHT tree respectively, find the total count of the nodes in the tree. class […]

    The post Binary tree (count nodes) interview question appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    Given a LEFT and a RIGHT property that returns the underlying LEFT tree and the underlying RIGHT tree respectively, find the total count of the nodes in the tree.
    class BinaryTree<T>
    {
    private BinaryTree<T> left;
    private BinaryTree<T> right;
    public int CountNodes<T>(this IBinaryTree<T> tree)
        {
            // TODO: What goes here?
         }    
    }
    Solution
    public int CountNodes<T>(this IBinaryTree<T> t) 
     {
       return  1 +  t.left.CountNodes() + t.right.CountNodes();
     }
     
          

    The post Binary tree (count nodes) interview question appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    https://www.anujvarma.com/binary-tree-count-nodes-interview-question/feed/ 0
    LINQ–search for items in a list that are present in another list https://www.anujvarma.com/linqsearch-for-items-in-a-list-that-are-present-in-another-list/ https://www.anujvarma.com/linqsearch-for-items-in-a-list-that-are-present-in-another-list/#respond Wed, 16 Jul 2014 02:23:24 +0000 http://www.anujvarma.com/?p=2632 Suppose you have a list of strings – a nursery rhyme may be a good example.  And you need to find ALL the words that match from another list of […]

    The post LINQ–search for items in a list that are present in another list appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    Suppose you have a list of strings – a nursery rhyme may be a good example.  And you need to find ALL the words that match from another list of words.

    Using LINQ to search a list for items in another list (should return a collection of all the matching words – “The,”, “Mouse”,”Up”

            var rhyme = "The mouse ran up the clock";
            private string[] wordsToSearchFor =
            {
                "The","mouse","up"
            };
    
            public IQueryable<string> FindWordsInRhyme()
            {
    
                var wordsFoundInRhyme = rhyme.Where(a => wordsToSearchFor.Count(i => a.ToString().Contains(i)) == 0);
                return wordsFoundInRhyme;
            }
    

    The post LINQ–search for items in a list that are present in another list appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    https://www.anujvarma.com/linqsearch-for-items-in-a-list-that-are-present-in-another-list/feed/ 0
    Filesystem notes from the real world–C# https://www.anujvarma.com/filesystem-notes-from-the-real-worldc/ https://www.anujvarma.com/filesystem-notes-from-the-real-worldc/#respond Tue, 10 Jun 2014 01:53:23 +0000 http://www.anujvarma.com/?p=2573 These are just some quick tidbits about file processing in C#.  Reading in files, reading in LARGE files, Reading and Processing Large Files. Reading a file (use a StreamReader) if […]

    The post Filesystem notes from the real world–C# appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    These are just some quick tidbits about file processing in C#.  Reading in files, reading in LARGE files, Reading and Processing Large Files.

    Reading a file (use a StreamReader)

    if (File.Exists(path))
                   {
                       using (StreamReader sr = new StreamReader(path))
                       {
                           while (sr.Peek() >= 0)
                           {
                               string line = sr.ReadLine();
                           }
                       }
                   }
    
    
     
    

    Fastest way to read a file (Reading a large file) – Use BufferedStream

    Using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {  using (BufferedStream bs = new BufferedStream(fs))  {
        using (StreamReader sr = new StreamReader(bs))
        {
          string line;
           while ((line = sr.ReadLine()) != null)
           {
    
           }
         }
       }
    }

    For large files, split up the Processing of the file – and the Reading of the file

    Use a producer – consumer pattern. The producer task read in lines of text using the BufferedStream and handed them off to a separate consumer task that did the searching.

    The post Filesystem notes from the real world–C# appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    https://www.anujvarma.com/filesystem-notes-from-the-real-worldc/feed/ 0
    Using Delegates in C# https://www.anujvarma.com/using-delegates-in-c/ https://www.anujvarma.com/using-delegates-in-c/#comments Thu, 14 Nov 2013 22:55:32 +0000 http://www.anujvarma.com/?p=1786 Introduction Delegates encapsulate a method. All they do is provide an alternate way to call (‘invoke’) a method. This concept has been around for a while (function pointers in C […]

    The post Using Delegates in C# appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    Introduction

    Delegates encapsulate a method. All they do is provide an alternate way to call (‘invoke’) a method. This concept has been around for a while (function pointers in C – and other languages). In C#, there are three things to remember when using delegates. Just use the acronym D-A-I  for ‘Declare’, ‘Assign’ and ‘Invoke’.

    Declaring a delegate

    Say you have a function that takes two strings, concatenates them and returns the result. So the signature would look something like the snippet below.

    private static string stringCat(string a, string b)

           {

               return String.Concat(a,b);

           }

    To encapsulate this function within a delegate, one declares a delegate as follows:

    delegate string del(string a, string b);

    Assigning a Delegate

    Once you have it declared (remember, it is simply encapsulating a function), you will need to specify which function you want to use it on. This is the assignment step – and is illustrated in the snippet below.

    private static string DelegateSimpleInvoke()

           {

               // assign your delegate to the stringCat target

               del x = stringCat; 

               // invoke the delegate (which means 'call your function' indirectly). This should return "ab"

               string c = x.Invoke("a","b");

               return c;

           }

    Invoking a Delegate

    Once you have assigned a target method for your delegate, you are ready to invoke the delegate (call the method). This is done via the Invoke keyword as shown above. This is where you would pass in the actual argument values to the function.

    So, there you have it. In three simple steps – D.A.I. – you can use delegates in C#.

    Asynchronous Invocation

    A nice advantage of encapsulating a method is that you can invoke it any way you like – synchronously (using Invoke) or asynchronously (using BeginInvoke).

    private static string DelegateAsyncInvoke()

          {

              // assign your delegate to the stringCat target

              del x = stringCat;

              // invoke the delegate (which means 'call your function' indirectly). This should return "ab"

              IAsyncResult result = x.BeginInvoke("a", "b",null,null);

              

              // Do something else while the method execution has not yet completed

              while (!result.IsCompleted)

              {

                  Thread.Sleep(500);

                  Console.Write(".");

              }

     

              // Now, the method has finished executing - since result.IsCompleted is true

              string c = x.EndInvoke(result);

     

              return c;

          }

    Common Misconception – Delegates and Async programming

    Most people associate the two. Delegates, by themselves, have nothing to do with an asynchronous model of programming. They simply encapsulate a function (any function). Now, once the function is encapsulated, it becomes possible to call it (invoke it) – synchronously OR asynchronously – as you choose. In the case of C#, the built-in delegate class provides you with supporting methods to invoke (the encapsulated method) asynchronously – which is why the misconception occurs. A delegate by itself, doesn’t care about whether you invoke synchronously or asynchronously. Only the client cares. The delegate’s job is to provide encapsulation for your method – and that’s it.

    Using a Lambda Expression with a delegate

    Notice that there is no assignment step like del x = stringCat in the snippet below. The assignment is done using a lambda expression. How does it know what x and y are? It ‘infers’ them based on the String.Contact function. It figures out that you will need to pass in two strings – and infers that x and y are strings.

    /// <summary>

           /// same thing as before - without an explicit assignment. Using a lambda expression for assignment.

           /// </summary>

           private static string DelegatesUsingLambdaExpr()

           {

               del z = (x,y) => String.Concat(x, y);

               return z.Invoke("a", "b");

           }

    Summary

    Delegates are a simple way to encapsulate methods – so that they can be called later. In addition to providing a way for ‘regular’ (synchronous) method invocation, they also provide an easy option to invoke the method asynchronously. Remember D.A.I (Declare, Assign and Invoke) to simplify usage of delegates within your codebase.

    The post Using Delegates in C# appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    https://www.anujvarma.com/using-delegates-in-c/feed/ 3
    The ‘params’ keyword in c# https://www.anujvarma.com/the-params-keyword-in-c/ https://www.anujvarma.com/the-params-keyword-in-c/#respond Wed, 23 Oct 2013 17:53:18 +0000 http://www.anujvarma.com/?p=1620 Introduction I was confused by the appearance of ‘params’ in the signature of a method (see example snippet below). It seemed redundant – even if I removed it, the method […]

    The post The ‘params’ keyword in c# appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    Introduction

    I was confused by the appearance of ‘params’ in the signature of a method (see example snippet below). It seemed redundant – even if I removed it, the method worked just fine.

    void DisplayStrings(params string[] strings);

    Params allows a short-cut during method invocation

    While the method itself is unaffected by the ‘params’ in its signature, the caller of the method is affected. The caller can, instead of specifying an array of values, simply pass in a list of values.  See the difference in the snippets below.

    Normal way of passing in values to this method (using an array)

    DisplayStrings(new string[]{"hello","world"})

    Params way (shortcut) of passing in values (no array needed, just pass in the values)

    DisplayStrings("Hello","World");

    Summary

    Params just allows a short-cut for passing in an array of values  to a method. Instead of initializing and passing an array, one can simply pass in the list of values (comma separated).

    The post The ‘params’ keyword in c# appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    https://www.anujvarma.com/the-params-keyword-in-c/feed/ 0
    Async and Await, an easy way to keep your user interface responsive https://www.anujvarma.com/async-and-await-an-easy-way-to-keep-your-user-interface-responsive/ https://www.anujvarma.com/async-and-await-an-easy-way-to-keep-your-user-interface-responsive/#respond Tue, 22 Oct 2013 22:11:00 +0000 http://www.anujvarma.com/?p=1566 Introduction Normally, when you invoke a method, it is invoked synchronously on your calling thread. Since you made no provision to ‘unblock’ the main thread, the method essentially ‘blocks’ the […]

    The post Async and Await, an easy way to keep your user interface responsive appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    Introduction

    Normally, when you invoke a method, it is invoked synchronously on your calling thread. Since you made no provision to ‘unblock’ the main thread, the method essentially ‘blocks’ the thread – which means that nothing else can happen until the method returns. What if your method was carrying out some time consuming task – such as writing a large file out to disk? Effectively, you would end up blocking the user interface (if that is where the method was invoked from), until this task was completed.

    Solution : The simple solution is to use something called callbacks (part of the asynchronous programming model). The main thread simply discharges its task to a secondary thread – and says ‘call me back’ when you are done. This way, I do not need for you to finish processing.

    While there are several ways to do asynchronous programming in .NET (manual use of the Thread class, delegates, BackgroundWorkers…), the most recent addition to this arsenal is the async-await duo. These two keywords simplify (somewhat) the process of executing methods asynchronously. They use callbacks behind the scenes, but thankfully, programmers are spared from having to deal with them explicitly. All we need to worry about are working with these three keywords – async, await and Task<T>. 

    A simple Long Running Task – carried out asynchronously

    The easiest way to understand these two keywords is to see a sample. The key points are:

    1. Your method uses the ‘async’ keyword in its declaration.
    2. Inside your method, you will need to do two things:
      • Use await somewhere inside your async method (if you fail to use await, the async method will run synchronously, Visual Studio warns you about this) 
      • Use a Task<t> to return values. Think of Task<int> as a wrapper for returning an int. The returned value will be of type int and not Task<int>. A Task by itself, does not return any value.
    3. That’s it – that’s all we need to get started (sample code is available for download at the end of this post).
    private static async void TaskWithoutBlocking()

      {

          Task<string> t = LongRunningTask();

          Console.WriteLine("See - I came right back. No blocking");

          string resultFromLongRunningTask = await t;

          Console.WriteLine("Result (of long running task) = " + resultFromLongRunningTask);

      }

    Your Task can be ANY task – even an Http request handling task

    The old way of writing a custom HTTP handler would have you inherit from IHttpHandler and override the ProcessRequest method (see example below). What if you wanted to write an async handler – because you are concerned that some of your HTTP requests will take a while to be processed – and you do not want to leave your web client hanging?

    OLD WAY (Synchronous HttpHandler)

    public class Handler : IHttpHandler

    {

           public void ProcessRequest(HttpContext context)

           {

               var action = context.Request.QueryString["action"];

               if (action == "json")

                {

                   var json = JsonConvert.SerializeObject(new Person(), Formatting.None);

                   context.Response.ContentType = "application/json";

                   context.Response.Write(json);

                }

           }

    }

    To deal with this scenario (handling http requests asynchronously), Microsoft offers a base class (HttpTaskAsyncHandler) containing a template method (ProcessRequestAsync). All we need to do is override this ProcessRequestAsync and we are set to go. The code snippet below demonstrates how to do this.

    NEW WAY (.net 4.5 – ASynchronous HttpHandler)

    public class CustomHttpHandler : HttpTaskAsyncHandler

    {

        public override async Task ProcessRequestAsync(HttpContext context)

        {

            string result = await DoLongRunningTaskAsync();

        }

     

        /// <summary>

        /// Simulate long running task. 

        /// NOTE: For simulating an async wait, we need to invoke something that returns an awaitable type (a Func is an awaitable type)             

        /// </summary>

        private static async Task<string> DoLongRunningTaskAsync()

        {

            Console.WriteLine("Entered long running task");

     

            // Thread.Sleep(5000) cannot be used - since it does not return an awaitable type;

     

            // We need an awaitable type here, func is an acceptable awaitable type 

            var func = Task<string>.Factory.StartNew(() => DoLongRunningSynchronousWork());

            string retValue = await func;

     

            Console.WriteLine("Finished long running task");

            return retValue;

        }

     

        /// Simulate a long running task

        /// For an infinite wait - try Thread.Sleep(Timeout.Infinite) 

        /// For simulating heavy processory usage - while (true){}           

        private static string DoLongRunningSynchronousWork()

        {

            Stopwatch sw = new Stopwatch();

            sw.Start();

            Console.WriteLine("This synchronous method was called asynchronously");

            Thread.Sleep(5000); // this is the long running task

            sw.Stop();

            return "Total time of long running synchronous method = " + sw.ElapsedMilliseconds + " milli seconds";

        }

    }

    Summary

    The async-await duo provide several powerful constructs, using just two keywords. For example, you can also  cancel running tasks (although it is a bit more work).

    The useful aspect of these keywords is that they can be applied to ANY task – just like you could run any task using System.Threading.Thread. However, here you can easily return types (even composite objects using Task<T>) and pass in any set of arguments.  It can be useful in cases where your task seems to be tying up (blocking) the client – such as due to a long running http request.

    Download Sample Solution

    The post Async and Await, an easy way to keep your user interface responsive appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    https://www.anujvarma.com/async-and-await-an-easy-way-to-keep-your-user-interface-responsive/feed/ 0
    The Publish Subscribe Pattern in C# and some gotchas https://www.anujvarma.com/the-publish-subscribe-pattern-in-c-and-some-gotchas/ https://www.anujvarma.com/the-publish-subscribe-pattern-in-c-and-some-gotchas/#comments Wed, 17 Apr 2013 19:48:50 +0000 http://www.anujvarma.com/?p=1440 This post does three things: Provides a complete implementation of the publish subscribe pattern in C#. Highlights 4 potential issues that are inherent to ANY publish subscribe implementation – including […]

    The post The Publish Subscribe Pattern in C# and some gotchas appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);}

    This post does three things:

    1. Provides a complete implementation of the publish subscribe pattern in C#.
    2. Highlights 4 potential issues that are inherent to ANY publish subscribe implementation – including the one provided here.
    3. Provides original, tested workarounds for each of the 4 issues (source code included).

    As far as the author is aware, this is the only publish subscribe implementation that provides these workarounds – making it immune from the common issues of badly behaved subscribers, race conditions and subscribers that fail to unsubscribe. 

    UPDATE: With the introduction of two new interfaces (IObserver and IObservable) in .NET 4.0, there is a cleaner way to implement the Publish Subscribe pattern in C# .NET. However, the ‘gotchas’ listed here still apply. Even with the new interfaces, one still needs to worry about things such as ‘unsubscribing from the publisher’, ‘badly behaved subscribers’ and ‘new subscribers added while publishing is in progress’.

    DELEGATES and EVENTS way OF IMPLEMENTING PUBLISH SUBSCRIBE in C#

     

    Introduction : Events , combined with delegates in C#  make it possible to implement a simple publisher – subscriber pattern. If you are unfamiliar with delegates, read this post first.

    There are three main players in any Publish Subscribe pattern implementation:

    1. The Event : The example below revolves around the ‘payday’ event – which is called PayrollArrived.
    2. The Publisher : The event is published by the Employer class (the Employer announces the payday when it arrives).
    3. The Subscriber : Each Employee (i.e. each instance of the Employee class) listens for the event – and is hence a subscriber to the PayrollArrived event.

     

    The Event

    Events provide a way to signal a change of state to whoever is ‘subscribed’ to that event. The arrival of the first of every month may be the event for publishing a new issue of a magazine. The subscribers would be everyone who has a paid subscription to the magazine – and the publisher would be the magazine publisher.

    The arrival of the 15th of every month may be a payroll event for a company. The subscribers would be all employees who get paid on the payroll date.  The publisher would be the company itself that pays the employees on payroll day. The example code in this post deals with the latter event – a payroll event with an Employer (Publisher) and multiple Employees(Subscribers). 

    // For events to be treated as 'fields', they need to be of type 'delegate'.

    // First, define the delegate type for the event 

       public delegate void PayrollArrivedHandler(object sender, PublisherEventArgs e);

     

    // public event declaration, a 'delegate' type for the event must be declared first

       public event PayrollArrivedHandler PayrollArrived;

    The Publisher (Employer)

    public class EmployerPublisher 

    {

        LinkedList<Employee> _listSubscribers = new LinkedList<Employee>();

        public LinkedList<Employee> ListSubscribers

        {

            get { return _listSubscribers; }

            set { _listSubscribers = value; }

        }

     

        // For events to be treated as 'fields', they need to be of type 'delegate'.

        // First, define the delegate type for the event 

        public delegate void PayrollArrivedHandler(object sender, PublisherEventArgs e);

     

        // public event declaration, a 'delegate' type for the event must be declared first

        public event PayrollArrivedHandler PayrollArrived;

      

        // add new subscriber

        public void AddSubscriber(Employee em)

        {

            // Add new subscriber to the TOP of the linked list - this way it will not interfere with the notification in progress

            this.ListSubscribers.AddFirst(em);

     

            // Subscribe the new subscriber to the event.

            // The coupling between the publisher publishing and the subscriber subscribing is via the common delegate

            this.PayrollArrived += em.OnPayrollArrival;

        }

     

        // This event firing is synchronous - i.e. the publisher instance is tied down until the subscriber finishes processing OnPayrollArrival

        public void FireEvent(DateTime dayToFireEvent)

        {

            PublisherEventArgs args = new PublisherEventArgs();

            args.DateToFireEvent = dayToFireEvent;

     

            if (PayrollArrived != null)

                PayrollArrived(this, args);

        }

     

        // This is an asynchronous version of the same event-firing - just fire it - 

        // and do not CARE about how long the subscriber takes - since subscriber processing is on a different thread.

        // This works around the 'Badly behaved subscriber - Gotcha 1'.

        public void FireEventAsynchronous(DateTime dayToFireEvent)

        {

            if (PayrollArrived != null)

            {

                PublisherEventArgs args = new PublisherEventArgs();

                // We have more than one subscriber - employee 1 and empoyee 2. Each one subscribes via its own delegate. 

                // so - we need to loop over all the delegates

     

                Delegate[] delegates = PayrollArrived.GetInvocationList();

                foreach (Delegate del in delegates)

                {

                    PayrollArrivedHandler handler = (PayrollArrivedHandler) del;

                    handler.BeginInvoke(this, args, null, null);

                }

            }

        }

     

        public void RemoveSubscriber(Employee em)

        {

            this.PayrollArrived -= em.OnPayrollArrival;

        }

    }

    The Subscriber (Employee)

    // Subscriber class – Employee – interested in knowing when the PayrollArrived event occurs

    public class Employee 

    {

       private string _name;

     

       public string Name

       {

           get { return _name; }

           set { _name = value; }

       }

     

       public Employee(string name)

       {

           this.Name = name;

       }

     

       public void OnPayrollArrival(object sender, PublisherEventArgs args)

       {

           DateTime dateToday = args.DateToFireEvent.Date;

     

           // Round up some friends and go spend the money!

           Console.WriteLine(this.Name + " was notified. Today is payday - date :" + dateToday);

       }

    }

    Most implementations out there have just the code above. They do not account for various things that can go wrong with a simple publish subscribe implementation.

     

    What can go wrong? (The 4 main potential issues with any publish-subscribe implementation)

     

    Gotcha 1 – The badly behaved subscriber

    One rotten apple – blocks the others. When multiple subscribers are present – what if one of the subscribers blocks the publisher so that it is effectively not available to other subscribers?  This can easily occur if any one of the subscribers decide to do something lengthy in its event handler. How do we prevent such an occurrence?

    Gotcha 2 – New Subscriber while notification is in progress

    What if a subscriber is added while notification is in progress? Supposing the list of subscribers is being notified – and a new subscriber happens to come along (this is not a rare event – especially if any one of the subscribers happens to contain time-consuming code as in Gotcha 1) . What happens to the new subscriber? Does it get dropped? Do we add it? If so – where and when do we add it?

    Gotcha 3 – Subscribers that fail to unsubscribe

    A  good practice in .NET eventing is to ensure that all subscribers eventually unsubscribe from their events – once they are done handling it. Failure to do so leads to potential memory leaks.  This is actually one of the more common sources of memory leaks in .NET applications.

    Gotcha 4 – Race conditions in the .NET framework

    Race conditions in the .NET eventing framework – leading to inconsistent handling of events.

    Workarounds for each of the Gotchas

     

    Gotcha 1 Workaround 

    The badly-behaved subscriber problem is best solved by working under the assumption that all subscribers will be badly behaved. So what is a publisher to do? One solution is to launch each notification on a new thread – that way even if a subscriber is badly behaved – it does not tie down the notification of other subscribers. Since the CLR in .NET provides a ready-made thread-pool, this is a seemingly simple solution. All one needs to do is use the built in support for asynchronous delegates (the event defined in the publisher class is really just a delegate – see sample below).

    // This is an asynchronous version of the same event-firing - just fire it - 

    // and do not CARE about how long the subscriber takes - since subscriber processing is on a different thread.

    // This works around the 'Badly behaved subscriber - Gotcha 1'.

    public void FireEventAsynchronous(DateTime dayToFireEvent)

    {

        if (PayrollArrived != null)

        {

            PublisherEventArgs args = new PublisherEventArgs();

            // We have more than one subscriber - employee 1 and empoyee 2. Each one subscribes via its own delegate. 

            // so - we need to loop over all the delegates

            Delegate[] delegates = PayrollArrived.GetInvocationList();

            foreach (Delegate del in delegates)

            {

                PayrollArrivedHandler handler = (PayrollArrivedHandler) del;

                handler.BeginInvoke(this, args, null, null);

            }

        }

    }

    We are almost there. The only problem with the above code is a C# restriction – if you want to call BeginInvoke, your delegate (our event) can only have one target. We already have two targets (employee1.OnPayrollArrival and employee2.OnPayrollArrival) – so what do we do? Just loop over all the targets of our delegate – and call BeginInvoke on them one at a time. That should work around the original problem.

    Gotcha 1 (Badly behaved subscribers) Workaround Summary

    The badly-behaved subscriber problem is essentially addressed by launching each subscriber on a separate thread (and letting the subscribers stay badly behaved). We just don’t care – we’ve still managed to notify all the subscribers successfully.

    Gotcha 2 (A subscriber is added while notification is in progress) Workaround

    This is a slightly trickier problem to solve. We still want to allow the new subscriber to add itself – but we do not want to interfere with the current notification process. This solution is borrowed from Holub on Patterns – and works well in our scenario as well. The basic idea is that instead of having just ANY collection of subscribers – use a linked list to store subscribers.

    Notification of the list of subscribers boils down to traversing the linked lists one node at a time. Say you are on some intermediate node – and a new subscriber arrives. Simply add the new subscriber (as a node) to the head of the list!

    This way – it doesn’t interfere with the existing notification process – and is successfully added to the list of subscribers whenever the next notification comes around.

     

    LinkedList<Employee> _listSubscribers = new LinkedList<Employee>();

    public LinkedList<Employee> ListSubscribers

    {

        get { return _listSubscribers; }

        set { _listSubscribers = value; }

    }

    // add new subscriber

       public void AddSubscriber(Employee em)

       {

           // Add new subscriber to the TOP of the linked list - this way it will not interfere with the notification in progress

           this.ListSubscribers.AddFirst(em);

    Gotcha 2  Workaround Summary

    Adding new subscribers while notification is in progress – is solved by ensuring that any new subscribers are added to the head of a linked list (containing all the subscribers)

    Gotcha 3: Subscribers that fail to unsubscribe

    The publisher holds a reference to every subscriber that has subscribed to its events. 2 subscribers – 2 references – 100 subscribers – 100 references. Unless each and every individual subscriber specifically unsubscribes after handling the event, the publisher does not release the reference to that subscriber. This leads to objects hanging around on the managed heap for longer than they are needed.

    To work around this, simply ensure that a RemoveSubscriber method is available that can be called ON each subscriber (by the publisher) when it is done with the subscriber.

    public void RemoveSubscriber(Employee em)

    {

         this.PayrollArrived -= em.OnPayrollArrival;

    }

    Gotcha 3 Workaround Summary

    Ensure that subscribers always unsubscribe from subscribed events when they are done. A simple RemoveSubscriber method as shown above can help accomplish this.

    Gotcha 4 : Race Condition in the .NET eventing framework

    This is not a publish-subscribe problem – but more an ‘eventing’ problem in the .NET framework. This ends up being a publish-subscribe problem nevertheless.

    // initialize to empty delegate to avoid Gotcha 4 - race condition      

     public event PayrollArrivedHandler PayrollArrived = delegate {} ;

    Gotcha 4 Workaround Summary

    A simple workaround is to ensure that the event is always initialized to an empty delegate – this way it will never be null.

    public event PayrollArrivedHandler PayrollArrived = delegate {} ;

     

    Summary

    The publish subscribe pattern is one of the most ubiquitous patterns in use today. Events and delegates in c# make it relatively simple to implement the pattern with a few lines of code. However, this implementation is prone to performance issues and potential bugs – if certain conditions are not handled up front.

    With the 4 workarounds described in this post, the publish subscribe implementation (in C#) is as close to unbreakable as possible. Subscribers can continue to be long running , poorly behaved. Race conditions can try and cause unanticipated interjections. The simple workarounds in the sample code will handle these conditions.

    These problems are especially noticeable when your event has a LARGE number of subscribers.

    Full Source Code

    Download Full Solution with the workarounds 

    References

    The post The Publish Subscribe Pattern in C# and some gotchas appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

    ]]>
    https://www.anujvarma.com/the-publish-subscribe-pattern-in-c-and-some-gotchas/feed/ 5