Запустить таймер в фоновом потоке - PullRequest
2 голосов
/ 23 июня 2011

Я ищу способ использовать System.Windows.Forms.Timer в потоке backgrounder.У меня много проблем с его запуском и остановкой в ​​фоновом потоке.Вот что я делаю:

private System.Windows.Forms.Timer chkTimer = new System.Windows.Forms.Timer();

Затем в методе backgroundworker_dowork у меня есть это:

     chkTimer.Interval = 2000;
     chkTimer.Tick += new EventHandler(chkTimer_Tick);
     chkTimer.Start();

В методе Tick у меня есть код, связанный с таймером, но он не будет работать длянекоторая причина.Если я заявляю выше в потоке пользовательского интерфейса, это работает.Может кто-нибудь, пожалуйста, помогите мне запустить таймер в фоновом потоке?Я не хочу использовать System.Timers, поэтому, пожалуйста, не предлагайте

Спасибо

Ответы [ 7 ]

2 голосов
/ 23 июня 2011

Я бы вообще не использовал таймер, его дополнительный багаж.Из того, что я прочитал, вы хотите иметь два потока: пользовательский интерфейс и фоновый поток.

Итак, фоновый поток управляет интервалом вместо таймера.

Код Psuedo:

YourFileChecker checker = new YourFileChecker();
checker.CheckInterval = 60000; //milliseconds, the background thread will manage the interval

System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(checker.Check));
t.Start();

Затем метод Check должен выполнить что-то вроде этого:

 while(!_Stop)
 {
      //Do your work here

      //Wait the specified interval before checking again...
      Thread.Sleep(_CheckInterval);
 }

Фоновый поток теперь просто продолжает проверку, пока ему не сообщат (не сообщат), что он остановился.Тогда вам вообще не нужен таймер, потому что поток управляет интервалом.

2 голосов
/ 05 января 2013
using System.Timers;
using System.Threading.Tasks;
.
.
.
var timer = new Timer(250);
.
.
.
private void Initialize()
{
    timer.Elapsed += (o, s) => Task.Factory.StartNew(() => OnTimerElapsed(o, s));
    timer.Start();
}
.
.
.
private void OnTimerElapsed(object o, ElapsedEventArgs s)
{
    //Do stuff
}

Вы также можете избавиться от параметров OnTimerElapsed "o" и "s", если хотите.

2 голосов
/ 23 июня 2011

Таймер форм работает, отправляя сообщения в дескриптор формы - сообщения, которые затем должны обрабатываться циклом сообщений формы.Фоновые потоки (обычно) не имеют циклов сообщений, поэтому сообщение WM_Timer, будучи опубликованным, никуда не денется (ваш обратный вызов не вызывается).

Что не так с использованием System.Timers?

1 голос
/ 23 июня 2011

Вы должны использовать только BackgroundWorker.Включите свойство BackgroundWorker WorkerSupportsCancellation.В методе DoWork добавьте:

while(!yourBGWorker.CancelationPending)
{
   //Do some work
   Thread.Sleep(2000);
}

Он делает то, что вы хотите - выполнить некоторую работу в фоновом потоке и ждать в течение определенного периода времени.Также вы можете отменить прогресс после звонка yourBGWorker.CancelAsync();

1 голос
/ 23 июня 2011

С документация :

Компонент Windows Forms Timer является однопоточным и имеет точность не более 55 миллисекунд. Если вам требуется многопоточный таймер с большей точностью, используйте класс Timer в пространстве имен System.Timers.

Большинство компонентов в пространстве имен System.Windows.Forms не предназначены для работы в фоновых потоках.

0 голосов
/ 14 сентября 2012

Я недавно написал статью, которая может быть именно тем, что вы ищете. Он демонстрирует в c # общий компонент опроса, который выполняется с заданным интервалом и использует фоновый поток для выполнения указанного действия пользователя. Вы можете запустить его в главном потоке, чтобы запустить событие в рабочем потоке.

Пример использования:

IPoller poller = new UrlPoller(args[0], TimeSpan.FromSeconds(7));
IPolling pollingComponent = new Polling.Core.Polling(poller);
pollingComponent.SubscribeForPollingUpdates(PollingAction);
pollingComponent.Start();

Для кода и полного использования:

http://www.avantprime.com/blog/24/an-example-of-repeating-code-using-a-worker-thread-without-using-timers-c

0 голосов
/ 23 июня 2011

System.Windows.Forms.Timer полностью основан на сообщениях Win32 и поэтому требует зацикливания сообщений.Другими словами, он может работать только в потоке пользовательского интерфейса.Альтернативой является System.Threading.Timer, который будет отмечен в отдельном потоке, но вы упоминаете, что он не будет работать для вас.Насколько я знаю, нет способа создать таймер, который будет отправлять в произвольный поток (однако вы можете выполнить диспетчеризацию самостоятельно).Технически, можно запустить второй цикл сообщений в вашем потоке и запустить там таймер Windows Forms, но я бы не рекомендовал его (вам нужно прокачать сообщения и т. Д.).Обычно есть лучший способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...