Click here to Skip to main content
12,759,844 members (30,584 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

10.7K views
2 bookmarked
Posted 12 Aug 2011

Execute later for delayed action

, 12 Aug 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
Code blocks are executed asyncronously in the UI thread after a given timeout.
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)

Share

About the Author

mll5
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170217.1 | Last Updated 12 Aug 2011
Article Copyright 2011 by mll5
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid