Jyunhao Shih
Jyunhao Shih

Reputation: 1479

In .NET console application, prevent Windows sleep/hibernate

I'm trying to write a .NET console application which sequentially downloads a list of file from web. The program basically works. The problem is that Windows' power-saving sleep mechanism interrupts the downloading. It seems that the SetThreadExecutionState approach doesn't work in console application?

using System.Runtime.InteropServices;
using System.Net;

public static class Utility {
  [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  public static extern ThreadExecutionState SetThreadExecutionState(ThreadExecutionState esFlags);
  [FlagsAttribute]public enum ThreadExecutionState: uint {
    CONTINUOUS = 0x80000000,
    DISPLAY_REQUIRED = 0x00000002,
    SYSTEM_REQUIRED = 0x00000001
  }
}

public class MyClass {
  void download(string[] urls) {
    var i = 0;
    Utility.SetThreadExecutionState(Utility.ThreadExecutionState.SYSTEM_REQUIRED);
    foreach(var url in urls) {
      using(var downloader = new WebClient()) {
        var lastTimeProgressMade = DateTime.Now;
        downloader.DownloadProgressChanged += (s, e) => { lastTimeProgressMade = DateTime.Now; };
        downloader.DownloadFileCompleted += (s, e) => { /* log exception, cancellation or completion... */ };
        downloader.DownloadFileAsync(new Uri(url), (++i).ToString());
        while(downloader.IsBusy) {
          Thread.Sleep(TimeSpan.FromSeconds(15));
          if(DateTime.Now - lastTimeProgressMade > TimeSpan.FromMinutes(3)) downloader.CancelAsync();
          Console.WriteLine(DateTime.Now);
        }
      }
    }
  }
}

Of course the above is simplified code. MyClass actually contains much more stuff. Anyway, in Main() an instance of MyClass is new'ed and its download() is called. While this program is running, with the keyboard and mouse don't get touched for a certain amount of time, my computer falls into sleep. After waking it up, with the messages I write to console, I can be sure that by the time when Windows was about to sleep the download is in progress. SetThreadExecutionState doesn't work. What can I do?

Upvotes: 2

Views: 2267

Answers (1)

David Heffernan
David Heffernan

Reputation: 613572

The documentation for SetThreadExecutionState says:

Calling SetThreadExecutionState without ES_CONTINUOUS simply resets the idle timer; to keep the display or system in the working state, the thread must call SetThreadExecutionState periodically.

So, either call it periodically, or include the ES_CONTINUOUS flag. The latter makes more sense, probably. But you should remember to restore the original state when you are done.

Upvotes: 3

Related Questions