Tuesday, August 2, 2011

Enforcing your object to be thread safe

Hi everyone, after a long time that i didn't write because i was on a long vacation, i wanted to share a very cool and simple code for enforcing thread safe calls to an object.

The motive was a lot of race conditions and deadlocks that happened to my team members so i found a solution for them by enforcing all the reading and writing to our model to be thread safe.
This is how i implemented it:

using System;
using System.Threading;
namespace MyCode {
   
   public class ThreadSafeObject<T>{
      private readonly ReaderWriterLockSlim _rwLock;
      private T _value;

      public ThreadSafeObject(T value){
         _rwLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
         _value = value;
      }

      public void SafeRead(Action<T> readFunction){
         try{
            _rwLock.EnterReadLock();
            readFunction.Invoke(_value);
         }
         finally{
            _rwLock.ExitReadLock();
         }
      }

      public void SafeWrite(Action<T> writeFunction){
         try{
            _rwLock.EnterWriteLock();
            writeFunction.Invoke(_value);
         }
         finally{
            _rwLock.ExitWriteLock();
         }
      }
   }
}

So as you can see, any access to my model (T) must go through a loch (read or write).

In our team, the T also implements an 'Observable' pattern so if a 'write' action is made inside read lock i actually throw 'IllegalOperationException' and also enforce that no write is performed in read lock.

Here is some code example of how to use it:

namespace MyCode {
    class Model {
      public int IntValue { get; set; }
      public string StringValue { get; set; }
   }

   class Example {
      public void ThreadSafeExample() {
         var threadSafeObject = new ThreadSafeObject<Model>(new Model());

         /// Writing values in a safe single transaction
         threadSafeObject.SafeWrite(state => {
            state.IntValue = 100;
            state.StringValue = "This is very cool design!!";
         });

         /// Reading values in a safe way (allow also multiple readers)
         var intValueRead = 0;
         var stringValueRead = string.Empty;
         var readingTime = DateTime.MinValue;
         threadSafeObject.SafeRead(state => {
            readingTime = DateTime.Now;
            intValueRead = state.IntValue;
            stringValueRead = state.StringValue;
         });

         Console.WriteLine("At {0} the model had in value of {1} and string value of: {2}", readingTime, intValueRead, stringValueRead);
      }
   }
}


This is it...

I hope it will be helpful for you as it was for me.

Gur

Wednesday, January 26, 2011

How to implement digital signature in .Net using RSA

Recently I was requested to make a automatic scenario test script for a third party co company.
I needed to find a way to get the results of the tests and to verify that everything passed the 'entry criteria'. In order to do that i made my script to generate a test log file with a result line for every method.
Before i go on, I must say that i fully trust my colleagues, but i though that it will be very cool if i can really verify that no one messes with that output file and to refresh my memory on things that i haven't use for a while and even share it with some people...

so... I wanted to make a digital signature of the output file.. i will not explain how the file and all the mechanism works but i'll give you my code of a simple RSA asymetric encryption algorithm.

In here I will demonstrate a most basic implementation but that should work for a quick dive.

So in my implementation i got 3 parts:
1. Generating public and private key
2. Encrypting
3. Decrypting


using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Tester {
   public static class Program {
      public static void Main() {
         const string privateKeyFile = @"C:\private.key";
         const string publicKeyFile = @"C:\public.key";

         DigitalSignProvider.GenerateKeysAndStoreOnFileSystem(publicKeyFile, privateKeyFile);

         var data = new byte[] { 1, 2, 3, 4, 5 };
         Console.WriteLine("Data: {0}", GetArrayString(data));

         var enData = DigitalSignProvider.Encrypt(publicKeyFile, data);
         Console.WriteLine("Encrypted Data: {0}", GetArrayString(enData));

         var deData = DigitalSignProvider.Decrypt(privateKeyFile, enData);
         Console.WriteLine("Decrypted Data: {0}", GetArrayString(deData));
      }

      private static string GetArrayString(IEnumerable array) {
         var str = new StringBuilder();
         foreach (var current in array) {
            str.AppendFormat("{0} ", current);
         }
         return str.ToString();
      }
   }

   public class DigitalSignProvider {
      const bool fOAEP = false;

      public static void GenerateKeysAndStoreOnFileSystem(string publicKeyPath, string privateKeyPath) {
         const int keyStrength = 512;
         var csp = new RSACryptoServiceProvider(keyStrength);
         var privateKey = csp.ExportCspBlob(true);
         var publicKey = csp.ExportCspBlob(false);

         using (var privateKeyFile = new FileStream(privateKeyPath, FileMode.Create)) {
            privateKeyFile.Write(privateKey, 0, privateKey.Length);
         }
         using (var publicKeyFile = new FileStream(publicKeyPath, FileMode.Create)) {
            publicKeyFile.Write(publicKey, 0, publicKey.Length);
         }
      }

      public static byte[] Decrypt(string keyPath, byte[] encryptedData) {
         var decryptionKey = File.ReadAllBytes(keyPath);
         var csp = new RSACryptoServiceProvider();
         csp.Clear();
         csp.ImportCspBlob(decryptionKey);
         return csp.Decrypt(encryptedData, fOAEP);
      }

      public static byte[] Encrypt(string keyPath, byte[] data) {
         var encryptionKey = File.ReadAllBytes(keyPath);
         var csp = new RSACryptoServiceProvider();
         csp.Clear();
         csp.ImportCspBlob(encryptionKey);
         return csp.Encrypt(data, fOAEP);
      }
   }
}


you can of course use your own key size or algorithm abstraction if you use the following
interface and abstract class: AsymmetricAlgorithm, ICspAsymmetricAlgorithm
under System.Security.Cryptorgraphy namespace


Enjoy


Gur

Friday, January 7, 2011

How to wrap InvokeRequired in WinForms using Extension Methods

Recently I saw a win form application that needs to print data to the UI from different threads.

As you probably know, for changing controls from a different thread other than the UI you need to use the InvokeRequired property of the control and then Control.Invoke method.

My very good friend Assaf had a very nice solution to the problem which is based on Extension Methods and lambdas. 

This is his solution:
public static class WinformExtenstions {
   public static void Write(this TControl control, Action action)where TControl:Control{
         if (control.InvokeRequired) {
            control.Invoke(action, control);
         } else{
            action(control);
         }
      }

      public static TValue SafeRead(this TControl control, Func action) where TControl : Control{
         if (control.InvokeRequired) {
            return (TValue)control.Invoke(action, control);
         }
         return action(control);
      }
}
This is an example of how to use:

public partial class Form1 : Form {
      readonly Timer _timer;
      public Form1() {
         InitializeComponent();
         _timer = new Timer(500);
         _timer.Elapsed += TimerElapsed;
      }

      void TimerElapsed(object sender, System.Timers.ElapsedEventArgs e) {
         textBox1.Write(control => { control.Text = DateTime.Now.ToString(); });
      }

      private void Form1_Load(object sender, EventArgs e) {
         _timer.Start();
      }
   }

I think this is a very elegant solution to the problem.

Hope this post was helpful

Gur

Monday, January 3, 2011

How to implement IAsyncResult and ISynchronizeInvoke

In this post I will demonstrate how to implement a sync object using the two .net classes IAsyncResult and ISynchronizeInvoke 


IAsyncResult will be used to store the action result
ISynchronizeInvoke will be used to synchronize all access to the resource that uses the sync object


class SimpleAsyncResult : IAsyncResult {
      object _state;


      public bool IsCompleted { get; set; }


      public WaitHandle AsyncWaitHandle { get; internal set; }


      public object AsyncState {
         get {
            if (Exception != null) {
               throw Exception;
            }
            return _state;
         }
         internal set {
            _state = value;
         }
      }


      public bool CompletedSynchronously { get { return IsCompleted; } }


      internal Exception Exception { get; set; }
   }


   class SimpleSyncObject : ISynchronizeInvoke {
      private readonly object _sync;


      public SimpleSyncObject() {
         _sync = new object();
      }


      public IAsyncResult BeginInvoke(Delegate method, object[] args) {
         var result = new SimpleAsyncResult();


         ThreadPool.QueueUserWorkItem(delegate {
            result.AsyncWaitHandle = new ManualResetEvent(false);
            try {
               result.AsyncState = Invoke(method, args);
            } catch (Exception exception) {
               result.Exception = exception;
            }
            result.IsCompleted = true;
         });


         return result;
      }


      public object EndInvoke(IAsyncResult result) {
         if (!result.IsCompleted) {
            result.AsyncWaitHandle.WaitOne();
         }


         return result.AsyncState;
      }


      public object Invoke(Delegate method, object[] args) {
         lock (_sync) {
            return method.DynamicInvoke(args);
         }
      }


      public bool InvokeRequired {
         get { return true; }
      }
   }


Hope the post was helpful