2014-01-12 81 views
1

我正在嘗試編寫一個.NET控制檯應用程序,它從Web順序地下載文件列表。該方案基本上可行。問題是Windows的節能睡眠機制會中斷下載。看起來SetThreadExecutionState方法在控制檯應用程序中不起作用?在.NET控制檯應用程序中,防止Windows睡眠/休眠

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的一個實例被new'ed並且它的download()被調用。當這個程序運行時,鍵盤和鼠標在一段時間內不會被觸摸,我的電腦會進入睡眠狀態。在喚醒之後,通過寫給控制檯的消息,我可以確定,在Windows即將進入休眠狀態時,正在進行下載。 SetThreadExecutionState不起作用。我能做什麼?

+1

SYSTEM_REQUIRED僅重置一次空閒計時器。你需要用CONTINUOUS或OR。你需要恢復它,保存返回值。 –

回答

2

SetThreadExecutionState文檔說:沒有ES_CONTINUOUS

調用SetThreadExecutionState僅復位空閒計時器;要使顯示或系統保持工作狀態,線程必須定期調用SetThreadExecutionState。

因此,要麼定期調用它,要麼包含ES_CONTINUOUS標誌。後者可能更有意義。但是你應該記得當你完成後恢復原來的狀態。

+0

謝謝。我真的應該把它們封裝成像Utility.keepWindowsAwake()這樣的函數來防止我再次犯這樣一個愚蠢的錯誤。 – user3187356