我正在尝试编写一个.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
不起作用。我该怎么办?
答案 0 :(得分:3)
在没有ES_CONTINUOUS的情况下调用SetThreadExecutionState只是重置空闲计时器;为了使显示器或系统保持工作状态,线程必须定期调用SetThreadExecutionState。
因此,要么定期调用它,要么包含ES_CONTINUOUS标志。后者可能更有意义。但是你应该记得在完成后恢复原始状态。