在.NET控制台应用程序中,阻止Windows睡眠/休眠

时间:2014-01-12 15:38:20

标签: .net windows console sleep

我正在尝试编写一个.NET控制台应用程序,它顺序从Web下载文件列表。该计划基本上有效。问题是Windows的省电睡眠机制会中断下载。似乎SetThreadExecutionState方法在控制台应用程序中不起作用?

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);
        }
      }
    }
  }
}

当然以上是简化代码。 MyClass实际上包含更多内容。无论如何,在Main()中,MyClass的一个实例是新的,并调用它的download()。当这个程序运行时,键盘和鼠标在一段时间内没有被触摸,我的电脑就会进入睡眠状态。唤醒它后,我写入控制台的消息,我可以肯定,当Windows即将睡眠时,下载正在进行中。 SetThreadExecutionState不起作用。我该怎么办?

1 个答案:

答案 0 :(得分:3)

SetThreadExecutionState的文档说:

  

在没有ES_CONTINUOUS的情况下调用SetThreadExecutionState只是重置空闲计时器;为了使显示器或系统保持工作状态,线程必须定期调用SetThreadExecutionState。

因此,要么定期调用它,要么包含ES_CONTINUOUS标志。后者可能更有意义。但是你应该记得在完成后恢复原始状态。