Showing posts with label Delegate. Show all posts
Showing posts with label Delegate. Show all posts

Tuesday, November 22, 2016

Pipelining events in C# .Net

The concept of Events is a good technique in .Net for establishing publisher-subscriber mechanism. When we work on .Net projects there would be situations where we have to raise an event when some of our dependency raise an event.

For example, our class A holds object of class B. A receive event BE1 from class B and fires AE1. A Simple event relay mechanism.

How that can be done inside class A?

Receive event and fires next event

class A
{
    B bObject=new B();
    public A()
    {
        InitializeB();
    }
 
    private void InitializeB()
    {
        bObject.BE1 += BObject_BE1;
    }
 
    private void BObject_BE1(object sender, EventArgs e)
    {
        this.OnAE1(e);
    }
 
    public event EventHandler AE1;
    protected virtual void OnAE1(EventArgs args)
    {
        if (AE1 != null)
        {
            AE1(this, args);
        }
    }
}
Below is the code for class B. It uses a simple timer to fire events.
class B
 {
     public event EventHandler BE1;
     protected virtual void OnBE1(EventArgs args)
     {
         if (BE1 != null)
         {
             BE1(this, args);
         }
     }
 
     #region Event raising code
 
     public B()
     {
         Timer t = new Timer(2000);
         t.Elapsed += (sender, args) => this.OnBE1(EventArgs.Empty);
         t.Start();
     }
 
     #endregion
 }

Passing the delegate

Lets see another technique for this event forwarding.
class A
{
    B bObject = new B();
   
    public event EventHandler AE1
    {
        add
        {
            this.bObject.BE1 += value;
        }
        remove
        {
            this.bObject.BE1 -= value;
        }
 
    }
}
Hope this property kind of syntax is familiar to all the .Net devs though it not used daily.
What are the differences?

Receive and fire

Passing delegate

The delegate of events can be different Delegates should be same
Even if the inner object is recreated there is no difference If the inner object is recreated event will not propagate
The sender of event will be originator classThe sender will be always the inner class
The intermediate class has to deal with dynamic event subscription in case there are multiple threadsIntermediate class don't need need to worry much about multiple threads
Happy coding.

Tuesday, November 15, 2016

How to make .Net process Singleton

Its a common scenario we encounter in traditional windows application development that we need to limit our process's instances to one. Especially if its a giant LOB WPF or WinForms which consumes good amount of memory, we will be forced to limit the instances of application to one. This post is explaining how that can be done.

Please note this is a solved problem. Many of us are doing it.

Using process name  

This is the most common method we can see to limit the process instance. Every time the process will check whether there is any other processes in the machine running with same name. Code snippet below
class ProcessHelper
{
    public void PrintIfThereIsAnotherProcessInstanceRunning()
    {
        IProcessInstanceDetection processDetection = new NameBasedDetection();
 
        bool areThereAnotherInstances = processDetection.IsAnotherInstanceRunning();
 
        Console.WriteLine($"Current process name {Process.GetCurrentProcess().ProcessName}.");
        Console.WriteLine($"Are there another instances : {areThereAnotherInstances}");
        //Handle the result.May be terminate second instance. 
    }
}
interface IProcessInstanceDetection
{
    bool IsAnotherInstanceRunning();
}
class NameBasedDetection : IProcessInstanceDetection
{
    public bool IsAnotherInstanceRunning()
    {
        return Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName)
                      .Count() > 1;
    }
}
class MutexBasedDetection : IProcessInstanceDetection
{
    private const string MutexName = "SomeGUID";
 
    public bool IsAnotherInstanceRunning()
    {
        bool created;
        Mutex mutex = new Mutex(true, MutexName, out created);
        return created == false;
    }
}
The interface is used for easily switching the logic. Here the name of the current process is used to get processes with same name and if there are more than one, current process may terminate. The code to terminate is not present in this sample.

First time when the process runs the count will be 1 and the process can continue. Next time the count will be 2 and its > 1 so the second process needs to be terminated itself. It's not a managed termination. Process has to exit itself. 

Pros

Simple mechanism to implement.

Cons

If someone rename the exe file name, the process name will change and second instance will run. Also if some other application from different vendor is also using the same exe name, our application will not run. Especially if our exe name is generic such a monitor.exe or starter.exe etc...  

Using Mutex

Here we use Mutex which is visible to all processes. The implementation class for the Mutex based duplicate process instance detection is below.
class MutexBasedDetection : IProcessInstanceDetection
{
    private const string MutexName = "SomeGUID";
 
    public bool IsAnotherInstanceRunning()
    {
        bool created;
        Mutex mutex = new Mutex(true, MutexName, out created);
        return created == false;
    }
}
Hope we all know what is Mutex means. If not please refresh. Here when the code is executed for first time, the Mutex will be created and it detect as first instance. Next time when the same process's different instance is started, the Mutex will not get created and the program can terminate itself.

Since the first code snippet is showing the usage, here only the new class is included.

One problem we can see here. If we use "SomeGUID" as Mutex name, there are chances for our logic to fail, if any other process create a Mutex with same name. So better generate a GUID and include that in our source code. Practically the same GUID will not be generated second time.

Pros

  • Even the exe is renamed, it will detect second process instance.

Cons

  • The Mutex name is the key part here. If its .Net, anyone can decompile the app and find the value if they really want to make trouble.
  • If same process try to check whether there are only single instance, the result may vary. So need to tweak the sample code above to handle.Please note its not because of this approach, its because of the logic in sample code.
We can think of many ways to make our process single instance. But these are the common ways.

Tuesday, October 11, 2016

What events do which delegates don't

Events v/s Delegates in .Net

If someone is a .Net developer he/she might have heard faced this famous question of what is the difference between events and delegates? Here the differences are summarized and given links to external sites as there are many resources available on the same and don't wanted to create another duplicate.

As everyone knows without delegates where is no event and event is just a multicast delegate. 

Invocation

The main difference is that event cannot be raised/invoked from outside of the class which declare it. If an object exposes a delegate as property or field anybody who has access to that property can invoke that delegate.

Protection

If we expose an delegate as public property, the consumers can overwrite other consumers. But in case of events its not possible. Events just add new subscriber to the existing list of subscribers.

Declaration

 An interface can declare and event and force the implementer to raise notification.This can be done by having a method in interface which accepts and delegate and get that invoked by implementer(s). But declaring event is more readable or easy to use.

Tuesday, September 6, 2016

Firing .Net events in separate thread

Suppose we are developing a library which has some events and we want our customers to handle the events in separate thread to make sure the UI is responsive. How can we do that?

Here is our class in the library which fires event every one second

class Clock
    {
        public event EventHandler<int> SecondChanged;
        DispatcherTimer timer;
        public Clock()
        {
            this.timer = new DispatcherTimer();
            this.timer.Interval = TimeSpan.FromSeconds(1);
            this.timer.Tick += Timer_Elapsed;
            this.timer.Start();
        }
 
        private void Timer_Elapsed(object sender, EventArgs e)
        {
            this.OnSecondChanged(DateTime.Now.Second);
        }
 
        protected virtual void OnSecondChanged(int second)
        {
            if(SecondChanged != null)
            {
                SecondChanged(this, second);
            }
        }
    }

Below is the code for handling the event normally. It handles the event in same thread and if it takes more time the UI will be unresponsive.
private void Clk_SecondChanged(object sender, int e)
{
    Log($"Event handler 1 - Second - {e}");
}

Lets see some approaches to handle event in separate thread.

Approach 1 - Guidelines to customers

Asking the customers to handle event handler in separate new thread or via ThreadPool is the simplest approach. But we don't get any guarantee that all are doing it right.
private void Clk_SecondChanged(object sender, int e)
{
    ThreadPool.QueueUserWorkItem((state) =>
    {
        Log($"Event handler 1 - Second - {e}");
    });
}

Approach 2 - Fire our event handlers in separate thread

Here we make sure each event handlers are executed in separate thread from the library itself. Below is the change required on firing method.
protected virtual void OnSecondChanged(int second)
{
    if (this.SecondChanged != null)
    {
        foreach (Delegate d in SecondChanged.GetInvocationList())
        {
            EventHandler<int> handler = d as EventHandler<int>;
            IAsyncResult ar = handler.BeginInvoke(this, second, null, null);
            handler.EndInvoke(ar);
        }
    }
    
}
Happy coding...

Monday, November 14, 2011

Generic retry mechanism & catch using generic exception type

Couple of weeks back we faced one situation where a portion of our code breaks due to a IIS not available situation and we were advised to implement a retry mechanism.Hope I can talk about that server down problem in future posts. The retry mechanism needs to implement based on the exception which will occur on that particular scenario. We tried test code by putting the try catch block and could see its working in one place. But there  are a bunch of other areas we need to modify the code.Also in future too developers may need to use this retry mechanism.
The architect resting in me jumped and said that we can use a generic retry mechanism using .net generics. My colleagues were in little confusion about how to achieve a generic mechanism for retry where the size and location of code differs and spread out in 150 projects.With the help of Action delegate I was able to convince them and the subsequent google gave us ready made code to do the same.
public static void ExecuteWithRetry( Action action, UInt16 noOfAttempts )
{
    //Validate args:Throw exception on retryCount=0
    int count = 1;
    for (; ; count++)
    {
        try
        {
            action();
            break;
        }
        catch (ReTryableException ex)
        {
            Log(ex, count);
            if (count == noOfAttempts) throw;
        }
    }
}

Everybody became happy like after the first fight seen in movies. We know that the movie needs to complete its 2 hours with excitement and for that villain  should come back with more power. Here too the villain come back when the perfectionist in me put forward the suggestion of making it real generic so that we can move to the utility project and can be consumed by other fellow developers as well. So we rewrote the logic as follows.


public static void ExecuteWithRetry<TException> ( Action action, UInt16 noOfAttempts ) where TException :Exception   
{
    //Validate args:Throw exception on retryCount=0
    int count=1;
    for(;;count++)
    {
        try
        {
            action();
            break;
        }
        catch (TException ex)
        {
            Log(ex, count);
            if (count == noOfAttempts) throw;
        }
    } 
}

Oh what an idea sir ji…There was one more suggestion came to make retry after specific interval. But before that we tried to integrate modified function in our app.

Catching exception using generic type

Here starts the second part of the story. When we run from Visual studio it didn’t hit the catch block!!! Theoretically there are no issues but practically it failed. At least for some moment surrounding people even I thought that our understanding about either Exception handling or generics is wrong. Even we thought of getting rid of this concept and write redundant retry code everywhere. But when we came back to our original state , we googled it and find that it is a BUG in .Net when running inside Visual Studio debugging mode.We tried running by double clicking the application and it works perfect.We were also able to see this bug in the Microsoft connect and says its fixed.

There is on workaround available for this issue its as follows

catch (Exception ex)
{
    TException tEx = ex as TException;
    if (tEx != null) { /*Process */}
    else throw;
}

This changed my perception

“The bug is there only due to poor dev’s coding mistake never by compilers, development tools or the framework”

to

“Compilers, development tools and frameworks are also coded by developers”.

Later I happen to read a post about fixing a compiler bug which enforced my perception.

Monday, July 12, 2010

Using Delegates for async method invocation

Problem

I want to call a method asynchronously in a synchronous environment. ie the subsequent lines should execute immediately after the method call regardless how much time the method takes to execute.

Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Debug.WriteLine("Before LongProcess")
TimeConsumingMethod()
Debug.WriteLine("After LongProcess")
End Sub
Private Sub TimeConsumingMethod()
'Imitating time consuming process using Thread.Sleep
System.Threading.Thread.Sleep(2000)
Debug.WriteLine("Done!!!")
End Sub



When we execute the above code it will result as follows.


Before LongProcess

Done!!!

After LongProcess


But what I want is

Before LongProcess

After LongProcess

Done!!!


The immediate answer

If we ask this question to any developer the immediate answer will be “use threading”.Yes that is correct we can use threading.But is there an other easier solution?


Solution

I was in the category of saying “threading” until I heard about the async method invocation using delegates.Here goes the solution.



  • Create a delegate to match with your long running method signature.

  • Declare a delegate variable and instantiate it by passing the address of the long running method.

  • Call the BeginInvoke Method of the delegate which calls the pointed method in asynchronous fashion.



Public Delegate Sub MyAsyncDelegate()
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Debug.WriteLine("Before LongProcess")

Dim del As MyAsyncDelegate = New MyAsyncDelegate(AddressOf TimeConsumingMethod)
del.BeginInvoke(Nothing, Nothing)

Debug.WriteLine("After LongProcess")
End Sub
Private Sub TimeConsumingMethod()
'Imitating time consuming process using Thread.Sleep
System.Threading.Thread.Sleep(20000)
Debug.WriteLine("Done!!!")
End Sub


Passing parameter

You can pass type safe parameters into this methods.For that just change the delegate signature.This automatically ask you to change the function which you are passing into delegate.



Public Delegate Function MyParamAsyncDelegate(ByVal data As String)

Private Function TimeConsumingMethod(ByVal data As String)
'Imitating time consuming process using Thread.Sleep
System.Threading.Thread.Sleep(20000)
Debug.WriteLine("Done!!! Parameter =" & data)
End Function

Private Sub btnCallParam_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Debug.WriteLine("Before LongProcess with param")

Dim del As MyParamAsyncDelegate = New MyParamAsyncDelegate(AddressOf TimeConsumingMethod)
del.BeginInvoke(tbData.Text, Nothing, Nothing)

Debug.WriteLine("After LongProcess with param")
End Sub



Processing return values in async method invocation

When we execute a method we might be expecting some values back after the processing.Now lets see how to get the return value.First change the signature of the method such that it returns something.Obviously return the value.

Now comes a new delegate named AsyncCallback which points to the async delegate execution completed method.We need to pass this delegate variable to the InvokeAsync method of our delegate.

The completed method should accept one parameter of type IAsyncResult which is must when we point using AsyncCallback.The importance of this variable comes when we need the return value.

First we need to cast to AsyncResult which is the concrete implementation of IAsyncResult.Then get the AsyncDelegate property which is our delegate and call the EndInvoke method on that.Confused??The change is only in the completed method where we process the return value.See the below code to get clarified.



Public Delegate Function MyParamAsyncDelegate(ByVal data As String) As Integer

Private Function TimeConsumingMethod(ByVal data As String) As Integer
'Imitating time consuming process using Thread.Sleep
System.Threading.Thread.Sleep(5000)
Debug.WriteLine("Done!!! Parameter =" & data)

'Return the length to read by completed method
Return data.Length
End Function

Private Sub btnCallBackParam_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Debug.WriteLine("Before LongProcess")
Dim delCallBack As MyParamAsyncDelegate = New MyParamAsyncDelegate(AddressOf TimeConsumingMethod)

Dim cb As AsyncCallback = New AsyncCallback(AddressOf TimeConsumingMethodCompleted)
Dim res As IAsyncResult = delCallBack.BeginInvoke(tbDataCallBack.Text, cb, Nothing)

Debug.WriteLine("After LongProcess")
End Sub

Private Sub TimeConsumingMethodCompleted(ByVal ar As System.IAsyncResult)
Dim asr As AsyncResult = DirectCast(ar, AsyncResult)
Dim del As MyParamAsyncDelegate = DirectCast(asr.AsyncDelegate, MyParamAsyncDelegate)
Dim result As Integer = del.EndInvoke(ar)
Debug.WriteLine("Async operation completed method.length of the string :" & result.ToString)
End Sub



Uploaded a sample here