Click here to Skip to main content
Click here to Skip to main content

Execute later for delayed action

By , 12 Aug 2011
 
This is the trick to be used in order invoke some piece of code in main UI thread after some delay without going through the BeginInvoke() stuff everytime. A possible use case is where an operation regarding an external device is performed and its status must be checked after some time. If device does not operate as requested or it does not respond at all, UI thread can show warning messages to inform the operator. Since warning messages will be shown in the UI thread, it is important that the delayed code is executed in the UI thread as well.
 
Timers and BeginInvoke with delegates can be used here as well but they make the code harder to follow in the case of many events and delegates.
 
Following class wraps up the delayed processing operations. It has a static method
which can be called from any thread. BackgroundWorker's RunWorkerCompleted method is used to execute the code later in the UI thread. Since the callback is executed in the UI thread, all operations on the UI control can be performed.
 public class DelayedAction
{ 
   public static void Do(int timeout, MethodInvoker callback)
   {
      BackgroundWorker worker = new BackgroundWorker();
      worker.DoWork += new DoWorkEventHandler(DoWork);
      worker.RunWorkerCompleted += new WorkerCompleted(RunWorkerCompleted);
      worker.RunWorkerAsync(new object[] { timeout, callback});
   }
 
   // Notified when our thread terminates
   static void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
   {
      MethodInvoker callback = (MethodInvoker)e.Result;
      callback.Invoke();
   }
 
   // Do nothing but sleep
   static void DoWork(object sender, DoWorkEventArgs e)
   {
      object[] args = (object[])e.Argument;
      Thread.Sleep((int)args[0]);
      e.Result = args[1]; // return callback
   }
}
 
After that we can easily use that class in our main UI thread as follows where we can easily track the business logic.
 
   ...
   label1.Text = "Powering on device";
   device.PowerOn();
 
   //Check device status 10 seconds later

   DelayedAction.Do(10000, (MethodInvoker)delegate()
   {
      // UI can be direcly manipulated here
      // This code executes in the UI thread. 
      if( device.IsPowered() == false )
      {   
         label1.Text = "Device operation failed";
      }
      else      
      {
         label1.Text = "Device OK.";
      }            
    });
    ...

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ayyhan
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 12 Aug 2011
Article Copyright 2011 by Ayyhan
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid