2014-01-12 6 views
1

Я пытаюсь написать консольное приложение .NET, которое последовательно загружает список файлов из Интернета. Программа в основном работает. Проблема в том, что энергосберегающий механизм сна 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 только один раз сбрасывает таймер простоя. Вам нужно ИЛИ с НЕПРЕРЫВНЫМ. И вам нужно восстановить его, сохранить возвращаемое значение. –

ответ

2

Документация SetThreadExecutionState говорит:

Вызов SetThreadExecutionState без ES_CONTINUOUS просто сбрасывает таймер простоя; чтобы дисплей или система находились в рабочем состоянии, поток должен периодически вызывать SetThreadExecutionState.

Таким образом, периодически вызывайте его или включайте флаг ES_CONTINUOUS. Последнее, вероятно, имеет больше смысла. Но вы должны помнить о восстановлении исходного состояния, когда вы закончите.

+0

Спасибо. Мне действительно нужно обернуть их как нечто вроде Utility.keepWindowsAwake(), чтобы я не повторил такую ​​глупую ошибку. – user3187356

Смежные вопросы