2015-07-22 2 views
0

Мне нужно сделать некоторые фоновые работы каждые 20 секунд (это не должно быть ровно 20000 мс, я могу позволить задержки). Я использую BackgroundWorker, который выполняет функцию, а затем ждать еще 20 секунд с помощью таймера:Использование фонового рабочего стола и процессора

private readonly BackgroundWorker Worker = new BackgroundWorker(); 
volatile bool keepWorkerRunning; 

Worker.DoWork += Worker_DoWork; 


    private void Worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     System.Timers.Timer aTimer = new System.Timers.Timer(); 
     aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
     aTimer.Interval = 20000; 
     aTimer.Enabled = true; 
     keepWorkerRunning = true; 
     while (keepWorkerRunning) ; 
     aTimer.Enabled = false; 
    } 

Этот работник действует в течение всего времени, в то время как программное обеспечение работает.

Проблема в том, что требуется большая часть процессора. Я заметил, что мое программное обеспечение все время использует около 70% процессора, и просто отключая фоновой рабочий, загрузка процессора падает до 0,5%.

Как я могу выполнить ту же работу без перегрузки процессора?

+1

Почему вы используете таймер и BackgroundWorker одновременно? Вы можете просто сделать то, что хотите сделать в обработчике «Tick» одного таймера, который тикает каждые 20 секунд. Кроме того, причиной использования ЦП, вероятно, не является конструкция BackgroundWorker/Timer, но ваш цикл занятости ('while (true)') – LInsoDeTeh

+0

Я помню, как копировал эту структуру из предыдущего сообщения или ответа. Он выполняет именно то, что мне нужно, но требует слишком большой мощности процессора. У вас есть альтернативное решение, которое займет меньше? Обратите внимание, что это должно быть сделано в другом потоке, чем в пользовательском интерфейсе. – Hamma

+0

Если вы действительно хотите пойти с этим решением, замените 'while (keepWorkerRunning);' с чем-то вроде 'while (keepWorkerRunning) {Threading.Thread.Sleep (100); } ', чтобы избавиться от цикла занятости, в котором вы занимаете полную мощность процессора. – LInsoDeTeh

ответ

2

Процессор съеден этого цикла:

while (keepWorkerRunning); 

Вы эффективно инструктировать CPU в цикле «ничего не делать» как можно быстрее. Следовательно, 70% загрузка процессора может быть еще хуже (до 100% в зависимости от вашего процессора/ядра).

Не использовать BackgroundWorker. Событие Elapsed поднимается Timer в потоке пула потока (SynchronizingObject свойство таймера должно быть null), поэтому оно будет работать в фоновом режиме.

Дополнительную информацию вы можете получить here.


Update: В соответствии с просьбой, вот пример.

using System.Timers; 

class MyClass : IDisposable 
{ 
    readonly Timer aTimer = new Timer(20000); 

    public void StartTimer() 
    { 
    this.aTimer.Elapsed += this.OnTimedEvent; 
    this.aTimer.Enabled = true; 
    } 

    void OnTimedEvent(object source, ElapsedEventArgs e) 
    { 
    // do your background work here 
    } 
} 
+0

Хорошо, я посмотрю на это, поскольку я не знаком с пулом потоков. Просто для информации, используя что-то вроде Thread.Sleep (20000) в Backgroundthread, будет потреблять столько же CPU, сколько сейчас? – Hamma

+0

@ Хамма, вам не нужно помещать 'Thread.Sleep()' в обработчик события, так как объект Timer' удается вызвать ваш обработчик каждые 20 секунд. – dymanoid

+0

У вас есть быстрая структура, с которой я могу следовать, чтобы реализовать Таймер? – Hamma

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