Mul$threaded	
  and	
  Async	
  
Programming	
  in	
  C#	
  +	
  File	
  IO	
  
              Jussi	
  Pohjolainen	
  
  Tampere	
  University	
  of	
  Applied	
  Sciences	
  
Delegates	
  
•  You	
  can	
  invoke	
  a	
  method	
  (determined	
  by	
  
   run$me)	
  from	
  a	
  delegate	
  
    public delegate int SomeMethod(int x, int y);

    Console.WriteLine("Thread is " +
    Thread.CurrentThread.ManagedThreadId);

    SomeMethod a = new SomeMethod(Sum);

    Console.WriteLine( a.Invoke(5,5) );
•  It's	
  possible	
  to	
  make	
  the	
  invoke	
  in	
  separate	
  thread!
Asynchronous	
  Delegate	
  
•  By	
  using	
  the	
  same	
  delegate,	
  but	
  calling	
  
   BeginInvoke,	
  the	
  method	
  is	
  done	
  in	
  separate	
  
   thread	
  
    –  public IAsyncResult BeginInvoke(parameters..,
       AsyncCallback cb, object state)
    –  public returnType EndInvoke(IAsyncResult result)

•  If	
  the	
  method	
  returns	
  something,	
  use	
  
   EndInvoke	
  to	
  get	
  the	
  return	
  value.
using System;
using System.Threading;
public delegate int SomeMethod(int x, int y);
class MyMain
{
     public static void Main()
     {
          SomeMethod a = new SomeMethod(Sum);
         Console.WriteLine("Firing Asynchronous method");
         // IAsyncResult - Represents the status of an asynchronous operation.
         IAsyncResult iftAR = a.BeginInvoke(5, 5, null, null);
         Console.WriteLine("Doing some work here!");
         int answer = a.EndInvoke(iftAR);
         Console.WriteLine(answer);
    }
    public static int Sum(int x, int y)
    {
         Console.WriteLine("Thread is " + Thread.CurrentThread.ManagedThreadId);
         Thread.Sleep(2000);
         return x + y;
    }
}
Synchronizing	
  Calling	
  Thread	
  
•  If	
  we	
  look	
  at	
  this	
  more	
  closely	
  
    –    Console.WriteLine("Firing Asynchronous method");
    –    IAsyncResult iftAR = a.BeginInvoke(5, 5, null, null);
    –    Console.WriteLine("Doing some work here!");
    –    // We are waiting here!
    –    int answer = a.EndInvoke(iftAR);
•  We	
  realize	
  that	
  the	
  a.EndInvoke	
  waits	
  un$l	
  the	
  
   "calcula$on"	
  is	
  done
using System;
using System.Threading;

public delegate int SomeMethod(int x, int y);

class MyMain
{
      public static void Main()
      {
            SomeMethod a = new SomeMethod(Sum);

           Console.WriteLine("Firing Asynchronous method");
           IAsyncResult iftAR = a.BeginInvoke(5, 5, null, null);

           while(!iftAR.IsCompleted)
           {
                 Console.WriteLine("Doing some work here!");
           }

           int answer = a.EndInvoke(iftAR);
           Console.WriteLine(answer);
     }

     public static int Sum(int x, int y)
     {
           Console.WriteLine("Thread is " + Thread.CurrentThread.ManagedThreadId);
           Thread.Sleep(2000);
           return x + y;
     }
}
Rid	
  of	
  Polling	
  
•  Instead	
  of	
  polling,	
  it	
  would	
  be	
  a	
  good	
  idea	
  to	
  
   have	
  a	
  secondary	
  thread	
  to	
  inform	
  the	
  calling	
  
   thread	
  when	
  the	
  task	
  is	
  finished.	
  
using System;
using System.Threading;

public delegate int SomeMethod(int x, int y);

class MyMain
{
       private static bool done = false;

      public static void Main()
      {
             SomeMethod a = new SomeMethod(Sum);

             Console.WriteLine("Firing Asynchronous method");
             IAsyncResult iftAR = a.BeginInvoke(5, 5, new AsyncCallback(Done), null);

             while(!done)
             {
                    Console.WriteLine("Doing some work here!");
             }

             int answer = a.EndInvoke(iftAR);
             Console.WriteLine(answer);
      }

      public static int Sum(int x, int y)
      {
             Console.WriteLine("Thread is " + Thread.CurrentThread.ManagedThreadId);
             Thread.Sleep(2000);
             return x + y;
      }

      public static void Done(IAsyncResult result)
      {
             done = true;
      }
}
using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;

public delegate int SomeMethod(int x, int y);

class MyMain
{
       private static bool done = false;
       public static void Main()
       {
              SomeMethod a = new SomeMethod(Sum);
              Console.WriteLine("Firing Asynchronous method");
             // Passing custom state data
              a.BeginInvoke(5, 5, new AsyncCallback(Done), "Message Sending!");
              while(!done)
              {
                     Console.WriteLine("Doing some work here!");
              }
       }
       public static void Done(IAsyncResult iftAR)
       {
              // IAsyncResult is interface, actual object is AsyncResult
              AsyncResult ar = (AsyncResult) iftAR;

             // AsyncResult holds the delegate
             SomeMethod sm = (SomeMethod) ar.AsyncDelegate;

             // Make the call
             int answer = sm.EndInvoke(iftAR);
             Console.WriteLine(answer);

             // Also print the message!
             string msg = (string) iftAR.AsyncState;
             Console.WriteLine(msg);

             done = true;
      }
}
THREADING	
  NAMESPACE	
  
Threading	
  Namespace	
  
•  Threading	
  namespace	
  provides	
  lot	
  of	
  classes	
  
   for	
  crea$ng	
  threads	
  
   –  Thread	
  –	
  Main	
  class	
  for	
  crea$ng	
  a	
  thread	
  
   –  ThreadStart	
  –	
  delegate	
  used	
  to	
  specify	
  which	
  
      method	
  is	
  run	
  under	
  a	
  thread	
  
   –  Timer	
  –	
  Mechanism	
  for	
  execu$ng	
  a	
  method	
  at	
  
      specified	
  intervals	
  
   –  Lot	
  of	
  locking	
  mechanisms	
  	
  
System.Threading.Thread	
  Class	
  
•  Some	
  sta$c	
  members	
  
    –  CurrentThread	
  –	
  get	
  the	
  current	
  thread	
  
    –  Sleep()	
  –	
  Suspend	
  current	
  thread	
  
•  Some	
  AZributes	
  
    –  IsAlive	
  
    –  Name	
  
    –  Priority	
  
•  	
  Some	
  Methods	
  
    –    Abort()	
  
    –    Join()	
  
    –    Start()	
  
    –    …	
  
Ge]ng	
  Informa$on	
  About	
  the	
  Current	
  
                    Thread	
  
using System;
using System.Threading;

class MyMain
{
     public static void Main()
     {
          Thread.CurrentThread.Name = "My THREAD!";

          Console.WriteLine("Name: ");
          Console.WriteLine(Thread.CurrentThread.Name);
          Console.WriteLine("IsAlive: ");
          Console.WriteLine(Thread.CurrentThread.IsAlive);
          Console.WriteLine("Priority: ");
          Console.WriteLine(Thread.CurrentThread.Priority);
          Console.WriteLine("ThreadState: ");
          Console.WriteLine(Thread.CurrentThread.ThreadState);
     }
}
using System;
using System.Threading;

public class Simple
{
   public static void DoThis()
   {
      int i=0;
      while (true)
      {
         Console.WriteLine("Running in its own thread. " + i);
         Thread.Sleep(500);
         i++;
      }
   }

    public static void Main()
    {
       Thread aThread = new Thread(new ThreadStart(DoThis));
       aThread.Start();
       Thread bThread = new Thread(new ThreadStart(DoThis));
       bThread.Start();
    }
}
using System;
using System.Threading;

public class Simple
{
   public static void DoThis(object data)
   {
      int i=0;
      while (i < (int) data)
      {
         Console.WriteLine("Running in its own thread. " + i);
         Thread.Sleep(500);
         i++;
      }
   }

    public static void Main()
    {
       Thread aThread = new Thread(new ParameterizedThreadStart(DoThis));
       aThread.Start(10);
    }
}
About	
  Locking	
  
•  When	
  mul$ple	
  threads	
  access	
  same	
  
   informa$on	
  -­‐>	
  unstable	
  data	
  
•  Example:	
  one	
  bank	
  account,	
  two	
  withdrawals	
  
   at	
  the	
  same	
  $me	
  
    –  1)	
  is	
  there	
  enough	
  money?	
  
    –  2)	
  if	
  true,	
  withdraw	
  
•  We	
  have	
  a	
  problem	
  if	
  these	
  steps	
  are	
  done	
  at	
  
   the	
  same	
  $me:	
  1,1,2,2	
  
Solu$on	
  
•    One	
  solu$on	
  is	
  to	
  use	
  lock	
  keyword	
  
•    If	
  on	
  thread	
  holds	
  a	
  lock,	
  others	
  wait	
  
•    lock	
  is	
  any	
  object	
  
•    Usage	
  lock(object){	
  	
  }	
  
Timers	
  
using System;
using System.Threading;

class Hello
{
      public static void DoThis(object data)
      {
            Console.WriteLine("Hello!");
      }

     public static void Main()
     {
           TimerCallback timeCB = new TimerCallback(DoThis);
           Timer t = new Timer(timeCB,   // call back delegate object
                                   null,   // Any info to the method
                                   0,      // Time before first invocation
                                   1000); // Interval

           Console.ReadLine();
     }
}
Background	
  Worker	
  
•  hZp://msdn.microsog.com/en-­‐us/library/cc221403(v=vs.95).aspx	
  
   private void Button_Click_2(object sender, RoutedEventArgs e)
      {
          BackgroundWorker bw = new BackgroundWorker();
          bw.DoWork += DoTheWork;
          bw.RunWorkerCompleted += Complete;
          bw.RunWorkerAsync();

      }

      public void DoTheWork(object sender, DoWorkEventArgs e)
      {
          Thread.Sleep(500);
      }

      public void Complete(object sender, RunWorkerCompletedEventArgs e)
      {
          Title = "Hello";
      }
GUI	
  AND	
  THREADING	
  
Access	
  UI	
  from	
  Thread	
  
•  If	
  a	
  secondary	
  thread	
  aZempt	
  to	
  access	
  a	
  control	
  it	
  did	
  not	
  
     create	
  =>	
  run$me	
  error!	
  
	
  
 private void Button_Click_2(object sender, RoutedEventArgs e)
 {
     Thread thread = new Thread(new ThreadStart(ModifyTitle));
     thread.Start();
}

// Runtime Exception!
public void ModifyTitle()
{
    Title = "Hello World";
}
Dispatcher	
  Class	
  
•  Dispatcher	
  class	
  allows	
  you	
  to	
  modify	
  UI	
  from	
  
   secondary	
  thread	
  
•  Read	
  
    –  hZp://msdn.microsog.com/en-­‐us/magazine/
       cc163328.aspx	
  
private void Button_Click_2(object sender, RoutedEventArgs e)
{
    Thread t = new Thread(new ThreadStart(ModifyTitle));
    t.Start();
}

public void ModifyTitle()
{
    Thread.Sleep(1000);

    // Change title to "Hello"
    Dispatcher.Invoke(new Action(ChangeTitle));

    Thread.Sleep(1000);

    // Lambda
    Dispatcher.Invoke(() => this.Title = "World");

    Thread.Sleep(1000);

    Dispatcher.Invoke(() => this.Title = "");

    string newTitle = "Hello World!";

    for (int i = 0; i < newTitle.Length; i++)
    {
        Thread.Sleep(100);
        Dispatcher.Invoke(() => this.Title += newTitle[i]);
    }
}

public void ChangeTitle()
{
    this.Title = "Hello";
}
Upda$ng	
  UI	
  and	
  Timer	
  
•  Timer	
  calls	
  certain	
  method	
  in	
  interval	
  
•  When	
  using	
  Threading.Timer	
  the	
  task	
  is	
  in	
  
   different	
  thread	
  
       –  Use	
  Dispatcher.Invoke	
  to	
  manipulate	
  the	
  UI	
  thread	
  
•  When	
  using	
  
   Windows.Threading.DispatcherTimer,	
  the	
  task	
  in	
  
   in	
  UI	
  thread	
  
       –  If	
  this	
  performs	
  a	
  $me	
  consuming	
  task,	
  the	
  UI	
  will	
  
          freeze	
  


	
  
ASYNC	
  CALLS	
  
Aync	
  Calls	
  Under	
  .NET	
  4.5	
  
•  Two	
  new	
  keywords	
  to	
  simplify	
  threading	
  even	
  
   more	
  
    –  async	
  and	
  await	
  
•  Compiler	
  will	
  generate	
  lot	
  of	
  code	
  when	
  using	
  
   these	
  keywords	
  
•  async	
  
    –  Method	
  should	
  be	
  called	
  in	
  an	
  asynchronous	
  manner	
  
       automa$cally	
  
•  await	
  
    –  Pause	
  current	
  thread	
  un$l	
  task	
  is	
  complete	
  
async	
  and	
  await	
  
•  In	
  .NET	
  4.5,	
  new	
  keywords:	
  async	
  and	
  await	
  
•  Simplifies	
  threading,	
  generates	
  a	
  lot	
  of	
  code!	
  
•  See:	
  
    –  hZp://blogs.msdn.com/b/pfxteam/archive/
       2012/04/12/10293335.aspx	
  
namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void Button_Click_1(object sender, RoutedEventArgs e)
        {
            WebClient wb = new WebClient();
            Task<string> result = wb.DownloadStringTaskAsync(new Uri("http://www.tamk.fi/"));

            string r = await result;

            Contents.Text = r;
        }
    }
}
FILE	
  I/O	
  
Overview	
  
•  System.IO	
  namespace	
  provides	
  number	
  of	
  classes	
  
   for	
  reading	
  and	
  wri$ng	
  
•  Store	
  and	
  retrieve	
  primi$ve	
  types	
  
    –  BinaryReader,	
  BinaryWriter	
  
•  Store	
  and	
  retrieve	
  text	
  
    –  StreamReader,	
  StreamWriter	
  
•  Buffered	
  reading	
  
    –  BufferedStream	
  
•  Helper	
  classes	
  like	
  File	
  (sta$c),	
  FileInfo	
  (object	
  
   reference	
  
Reading	
  and	
  Wri$ng	
  Text	
  
•  StreamWriter	
  and	
  StreamReader	
  use	
  useful	
  
   when	
  need	
  for	
  read	
  or	
  write	
  text	
  
•  By	
  default:	
  Unicode	
  
   –  Can	
  be	
  changed:	
  pass	
  System.TextEncoding	
  object	
  
      reference	
  
•  Methods	
  
   –  Write(),	
  WriteLine()	
  
Wri$ng	
  
class SaveText
{
    public static void Main()
    {
        StreamWriter writer = File.CreateText("./textfile.txt");
        // Nothing happens! Why?
        writer.WriteLine("Hello World!");
        writer.WriteLine("Hello World!");
    }
}
Wri$ng:	
  Flush	
  it!	
  
using System;
using System.IO;

class SaveText
{
    public static void Main()
    {
        StreamWriter writer = File.CreateText("./textfile.txt");

        writer.WriteLine("Hello World!");
        writer.WriteLine("Hello World!");
        writer.Flush();
    }
}
Wri$ng:	
  Stream	
  should	
  be	
  closed!	
  
using System;
using System.IO;

class SaveText
{
    public static void Main()
    {
        StreamWriter writer = File.CreateText("./textfile.txt");

         writer.WriteLine("Hello World!");
         writer.WriteLine("Hello World!");
         writer.Flush();
         writer.Close();
     }
}
Wri$ng:	
  Flushing	
  is	
  done	
  when	
  
                      closing!	
  
using System;
using System.IO;

class SaveText
{
    public static void Main()
    {
        StreamWriter writer = File.CreateText("./textfile.txt");

        writer.WriteLine("Hello World!");
        writer.WriteLine("Hello World!");
        writer.Close();
    }
}
Wri$ng:	
  using	
  
using System;
using System.IO;

class ReadText
{
     public static void Main()
     {
          using( StreamWriter writer = File.CreateText("./textfile.txt") )
          {
               writer.WriteLine("Hello World!");
               writer.WriteLine("Hello World!");
          }
     }
}
Reading	
  Text	
  
using System;
using System.IO;

class ReadText
{
     public static void Main()
     {
          using( StreamReader reader = File.OpenText("./textfile.txt") )
          {
               string input = null;
               while((input = reader.ReadLine()) != null)
               {
                    Console.WriteLine(input);
               }
          }
     }
}
Reading	
  and	
  Wri$ng	
  Binary	
  
using System;
using System.IO;

class ReadBinary
{
     public static void Main()
     {
          using( BinaryWriter writer = new BinaryWriter( File.OpenWrite("./test.dat") ) )
          {
               writer.Write(2.2);
          }

          using( BinaryReader reader = new BinaryReader( File.OpenRead("./test.dat") ) )
          {
               Console.WriteLine(reader.ReadDouble());
          }
     }
}
Watching	
  Files	
  
•  Monitor	
  or	
  watch	
  files	
  using	
  
   FileSystemWatcher	
  class	
  
•  Really	
  easy	
  to	
  implement	
  
    –  Which	
  folder	
  are	
  we	
  looking?	
  
    –  Set	
  up	
  things	
  to	
  listen	
  
    –  Add	
  Filters	
  
    –  Add	
  Event	
  Handlers	
  
    –  Start	
  listening	
  
Example	
  
using System;
using System.IO;

class Watcher
{
      public static void Main()
      {
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = "/Users/pohjus/Desktop/tuhoa/";
            watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName;

           watcher.Filter = "*.txt";

           watcher.Changed += (object source, FileSystemEventArgs e) => Console.Write("Changed");
           watcher.Deleted += (object source, FileSystemEventArgs e) => Console.Write("Deleted");

           watcher.EnableRaisingEvents = true;

           Console.Read();
     }
}
Serializable	
  
•  Serializa$on?	
  Store	
  an	
  state	
  of	
  the	
  object	
  into	
  
   stream!	
  
•  Example:	
  Store	
  app	
  preferences	
  into	
  a	
  file.	
  
   Preference	
  informa$on	
  are	
  stored	
  in	
  object.	
  
•  How?	
  Mark	
  a	
  class	
  as	
  Serializable	
  and	
  use	
  
   classes	
  to	
  store	
  and	
  open	
  the	
  object	
  
•  You	
  can	
  save	
  the	
  object	
  as	
  binary	
  or	
  xml	
  (use	
  
   XMLSerializer	
  -­‐	
  class)	
  
using	
  System;	
  
using	
  System.IO;	
  
using	
  System.Run$me.Serializa$on.FormaZers.Binary;	
  
	
  
[Serializable]	
  
class	
  Person	
  
{	
  
         	
  public	
  string	
  Name	
  {	
  get;	
  set;	
  }	
  
         	
  public	
  int	
  Age	
  {	
  get;	
  set;	
  }	
  
}	
  
class	
  SerializableExample	
  
{	
  
         	
  public	
  sta$c	
  void	
  Main()	
  
         	
  {	
  
         	
        	
  Person	
  jack	
  =	
  new	
  Person()	
  {	
  Name	
  =	
  "Jack",	
  Age	
  =	
  20	
  };	
  
	
  
         	
        	
  //	
  Let's	
  save	
  jack	
  as	
  binary	
  
         	
        	
  BinaryFormaZer	
  binFormat	
  =	
  new	
  BinaryFormaZer();	
  
	
  
         	
        	
  //	
  And	
  in	
  which	
  file?	
  
         	
        	
  using(FileStream	
  fs	
  =	
  new	
  FileStream("person.dat",	
  FileMode.Create))	
  
         	
        	
  {	
  
         	
        	
           	
  //	
  Let's	
  do	
  it!	
  
         	
        	
           	
  binFormat.Serialize(fs,	
  jack);	
  
         	
        	
  }	
  
         	
  }	
  
}	
  
	
  
using	
  System;	
  
using	
  System.IO;	
  
using	
  System.Run$me.Serializa$on.FormaZers.Binary;	
  
	
  
[Serializable]	
  
class	
  Person	
  
{	
  
         	
  public	
  string	
  Name	
  {	
  get;	
  set;	
  }	
  
         	
  public	
  int	
  Age	
  {	
  get;	
  set;	
  }	
  
}	
  
	
  
class	
  SerializableExample	
  
{	
  
         	
  public	
  sta$c	
  void	
  Main()	
  
         	
  {	
  
         	
        	
  BinaryFormaZer	
  binFormat	
  =	
  new	
  BinaryFormaZer();	
  
	
  
         	
        	
  //	
  Deserialize!	
  
         	
        	
  using(FileStream	
  fs	
  =	
  new	
  FileStream("person.dat",	
  FileMode.Open))	
  
         	
        	
  {	
  
         	
        	
           	
  Person	
  jack2	
  =	
  (Person)	
  binFormat.Deserialize(fs);	
  
         	
        	
           	
  Console.WriteLine(jack2.Name);	
  
         	
        	
           	
  Console.WriteLine(jack2.Age);	
  
         	
        	
  }	
  
         	
  }	
  
}	
  
ABOUT	
  WIN	
  DESKTOP	
  APPS	
  
WPF	
  
•  Windows	
  Presenta$on	
  Founda$on	
  (or	
  WPF)	
  is	
  
   a	
  computer-­‐sogware	
  graphical	
  subsystem	
  for	
  
   rendering	
  user	
  interfaces	
  in	
  Windows-­‐based	
  
   applica$ons	
  
•  WPF	
  employs	
  XAML,	
  an	
  XML-­‐based	
  language,	
  
   to	
  define	
  and	
  link	
  various	
  UI	
  elements	
  
•  See	
  
   –  hZp://msdn.microsog.com/en-­‐us/library/
      ms752299.aspx	
  
.NET Multithreading and File I/O
.NET Multithreading and File I/O
.NET Multithreading and File I/O
.NET Multithreading and File I/O
.NET Multithreading and File I/O