Click here to Skip to main content
15,886,106 members
Articles / Desktop Programming / Windows Forms
Article

The Sleep() Function in .NET

Rate me:
Please Sign up or sign in to vote.
1.42/5 (21 votes)
17 Oct 20078 min read 176K   959   18   12
Where are your favorite Windows APIs in the .NET Framework? This article points out where the Windows Sleep() function now can be found.
Sleep.NET Main WindowSleep.NET Main Window
Figure 1. The Sleep.NET Main Window
Figure 2. User feedback while sleeping

Introduction

I am just starting out with Windows Forms and .NET programming in general and I am learning my trade all over again. My background is as a C++/Win32 GUI and DCOM programmer with a strong MFC and Win32 Functions emphasis.

I relented and now do Windows Forms and ASP.NET programming, and I have discovered how effortless .NET development is when using Microsoft's excellent tool, Visual Studio 2005 and up. Truth is, I am never going back. My personal preference is to use .NET and the visual tools provided by Microsoft to do my development from now on. Unmanaged C/C++ and MFC is not worth the extra time I see myself spending using those languages.

About This Series

However, now that I am coming to my trade all over again in some sense, I am having to learn where my old familiar Windows API functions are in the .NET world. I am sure I am not alone as there are other .NET beginners out there.

Audience

This series, "The ____ in .NET," is something I am going to publish on The Code Project from time to time in an effort to provide beginners and newbies with quick, piecemeal tutorials on your favorite functionality. This is not a re-hash of the VS "How Do I?..." docs, since they provide more comprehensive help. These are "tutorials to go," that focus very narrowly on one or other individual functionality items.

Language Used

Because my employer is having me do things in C#, the sample code provided with the articles in this series will all be in C#. I take it Visual Basic, etc., developers are smart, intelligent, capable people who can translate between languages as necessary.

Background

In Windows, APIs are provided to suspend threads and processes for a programmer-specified time period, usually given in milleseconds. In the old, Visual Studio-6.0-and-below-esque, unmanaged C++ and MFC, one could suspend the current thread (i.e., make your window stop responding) as such:

C#
// A BN_CLICKED message handler
void CMyDialog::OnClickedSleep()
{
    // Delay the program from responding for 1/2-second
    ::Sleep(500);
    // Program is again responding
}
Listing 1. A MFC message handler calling the Win32 function, ::Sleep()

Question is, where does this Sleep() function sit in the new .NET Framework?

To suspend an application, you must call the System.Threading.Thread.Sleep() static method. It takes one parameter, an int specifying the delay, in milliseconds.

This concludes this article. If you are a beginner and want help implementing this in your application, I invite you to follow the tutorial below to build the sample application distributed with this article.

Tutorial: Sleep.NET

This article presents a small sample Windows Forms application, Sleep.NET, demonstrating the use of the System.Threading.Thread.Sleep() static method.

Step 1: Open your copy of Visual Studio.NET

Step 2: Click the File menu, point to New, and then click Project

  • Visual Studio opens the New Project window.

Step 3: In the Project Types box on the left, click Visual C#, and then click Windows

  • If it is your personal preference, you may also choose your .NET language of choice to implement this tutorial in. It must be Windows Forms-compatible.

Step 4: In the Templates box on the right, under Visual Studio installed templates, click Windows Application

Step 5: In the Name box, type Sleep.NET

  • You may use whichever name you choose if you're following along; here, we shall use Sleep.NET.

Step 6: Using the Visual Studio Forms Designer -- which I am going to leave the use of for you to learn -- create a main form to match Figure 1 above.

  • In my form, the Sleep for: text box was given the Name property txtSleep
  • I assigned the value btnSleep for the Sleep button's Name property
  • I assigned the value btnQuitfor the Quit button's Name property
  • I set the form's AcceptButton property to btnSleep and the form's CancelButton property I set to have the value btnQuit

Step 7: Once your form has been created, press CTRL+F5 to build and run the project, so as to test. In order to kill the app, you will have to press the ALT+F4 keys on your keyboard.

Step 8: Purely for aesthetics, we're going to program the form window to center itself on the screen before it's shown. Double-click anywhere in a blank area of the form.

  • The code window opens, with the insertion point on the Form1_Load event handler
  • For help on this event handler, lookup Form.Load (Windows Forms) in the docs

Step 9: Implement the Form1_Load event handler as follows:

C#
private void Form1_Load(object sender, EventArgs e)
{
    CenterToScreen(); Show();
    titleOld = this.Text;        /* save the default window title */
}
  • This listing saves the window's default title -- since we update the title when we're sleeping to indicate so to the user, shown below.

Step 10: Add a field to the Form1 class to store the window's default title. Open the Form1.cs file and add the code shown below:

C#
namespace Sleep.NET
{
    public partial class Form1 : Form
    {
        String titleOld;

        ...
    }
}

Step 11: Double-click the Quit button in the Designer, which brings you to code for the btnQuit_Click event handler. Implement the handler as shown below:

C#
private void btnQuit_Click(object sender, EventArgs e)
{
    Hide(); Application.Exit();
}

Step 12: Double-click the Sleep button in the Designer, and add the following code:

C#
private void btnSleep_Click(object sender, EventArgs e)
{
    // sleep the application for the time period specified
    // by the user -- during the sleep, gray out the text box

    // user interface - gray out the text box and change this form's
    // title to provide user feedback
    EnableUI(false);

    // the 'meat'
    Int32 SleepTime = 0;
    if (Int32.TryParse(txtSleep.Text, out SleepTime)) {
    System.Threading.Thread.Sleep(SleepTime);
    }

    // change the user interface again - ungray the text box and put
    // back the same window title on this form
    EnableUI(true;)
}

Step 13: Add the EnableUI() method to the Form1 class, implemented as shown below.

  • This method enables/disables the text box specifying the time to sleep for, enables/disables the Sleep button, and updates the form's title to reflect its status.
C#
private void EnableUI()
{
     txtSleep.Enabled = Enabled;
     this.Text = Enabled ? titleOld : "Sleep.NET - Sleeping";
     btnSleep.Enabled = Enabled;
     Refresh();
}

Step 14: Press CTRL+S on your keyboard to save your changes, and then CTRL+F5 in order to build and test the sample code.

  • To test the sample code, enter a number of milliseconds (1 second = 1000 milliseconds) in the Sleep for: box, and then click Sleep. The title bar changes to say Sleeping, and the text box is grayed out for the duration of the sleep
  • Experiment and try some other lengths of time and see the resulting behavior.
  • When finished, close the sample application by clicking Quit or pressing ESC.

Points of Interest

In this section, we shall review interesting facts and .NET features learned while implementing the sample. Among these are:

  • Message-pumping -- in order to update the user-interface (UI) -- with Control.Refresh()
  • You can also refresh the form by calling its Refresh() method
  • Using Refresh() is more thread-safe than, e.g., Application.DoEvents()
  • Converting a String value to a 32-bit int value (to pass to the Sleep function) with Int32.TryParse()

I want to take a moment and acknowledge message board posters dubbele onzin and norm .net below for their comments about avoiding the use of Application.DoEvents() in favor of Refresh().

Refresh()

Notice the setting of properties of controls to, say, enable or disable them, or change the text. Note that when using Sleep(), the application's Windows messages must be pumped (i.e., collected and distributed to all message handlers) or else the controls will not visibly change their state.

In the days of yore, or for those unlucky enough to still be maintaining legacy Win32 code, the way to pump messages is to run a message loop:

C#
void MessageLoop()
{
    MSG msg;
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
}
Listing 2. A legacy Win32 message pump

or some variant thereof, as appropriate to one's application. With .NET, things are simpler, and in particular only one line of code accomplishes the same. Note that the function shown below can be called either for the whole form, or the control whose UI you want to refresh. This is shown in 'Listing 3' below:

C#
Refresh();
Listing 3. A message pump run in .NET (C#)

Whenever you change a UI-visible property of a control, such as Enabled, you want to make sure and force the UI to update with a call to Control.Refresh() before you implement other functionality.

Int32.TryParse()

The int type -- as well as the other types -- appears to implement the TryParse() method, which takes as parameters a string and an out parameter which is the type into which to convert the string. The useful aspect of this method is that it returns false if there is garbage in the string and you can simply avoid processing the result if this occurs, as is shown in 'Listing 1'.

C#
Int32.TryParse(string s, out Int32 result)

Notice how an out parameter is used. You first declare an instance of the variable to which the parsed value should be assigned. Next, supply the variable to the out parameter, with the out keyword in front of the variable name. Finally, test the method's return value for true before using the result.

Where To Go for Help

Feel free to email me with specific questions about this article, and I will be happy to explain. I also want to invite you to make use of the Forums at the bottom of this article. I wish you well.

History

In this section, I will keep a running history of the changes and updates I've made to this article.

  • 16 Oct 2007 9:08 AM Pacific
    Article updated to reflect the use of Refresh() in lieu of Application.DoEvents() to update the UI, and the use of Int32.TryParse() in lieu of Convert.ToInt32() as per reader feedback and tips (see below)
  • 11 Oct 2007 12:46 PM Pacific
    Article written

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Team Leader
United States United States
Brian C. Hart, Ph.D., is a strategic engagement leader on a mission to leverage space technology to protect U.S. interests and assets against adversaries. Throughout Dr. Hart's career, he has enjoyed: Working closely with business executives to provide strategic direction and leadership, translating customer and competitive intelligence into compelling capture strategies and solutions, and mentoring teams to enhance individual and company capabilities while fostering an engaging and accountable environment, being involved in STEAM initiatives and education to develop greater awareness in the community, and serving the armed forces with the U.S. Navy and U.S. Army National Guard. He is excited to begin developing his career in Jacobs's Critical Mission Systems business unit, supporting NORAD and the U.S. Space Force.

Comments and Discussions

 
GeneralBad Code Pin
tommyligo16-Oct-07 9:38
tommyligo16-Oct-07 9:38 
GeneralRe: Bad Code Pin
Brian C Hart16-Oct-07 15:42
professionalBrian C Hart16-Oct-07 15:42 
GeneralRe: Bad Code Pin
senfo_9925-Oct-07 14:09
senfo_9925-Oct-07 14:09 
GeneralRe: Bad Code Pin
hemanta_dasa27-Oct-07 3:55
hemanta_dasa27-Oct-07 3:55 
GeneralRe: Bad Code Pin
buzz10031-Mar-13 12:54
buzz10031-Mar-13 12:54 
GeneralNEVER use Applicaiton.DoEvents() Pin
dubbele onzin15-Oct-07 9:38
dubbele onzin15-Oct-07 9:38 
GeneralRe: NEVER use Applicaiton.DoEvents() Pin
Brian C Hart16-Oct-07 6:01
professionalBrian C Hart16-Oct-07 6:01 
GeneralRe: NEVER use Applicaiton.DoEvents() Pin
senfo_9925-Oct-07 14:17
senfo_9925-Oct-07 14:17 
GeneralRe: NEVER use Applicaiton.DoEvents() Pin
Joe Sonderegger17-Oct-07 19:39
Joe Sonderegger17-Oct-07 19:39 
GeneralRe: NEVER use Applicaiton.DoEvents() Pin
senfo_9925-Oct-07 14:22
senfo_9925-Oct-07 14:22 
GeneralRe: NEVER use Applicaiton.DoEvents() Pin
buzz10031-Mar-13 12:52
buzz10031-Mar-13 12:52 
GeneralPointers Pin
NormDroid15-Oct-07 2:19
professionalNormDroid15-Oct-07 2:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.