2011-04-20 3 views
13

Привет, я вмешался в некоторые проблемы, связанные с таймером. надежда кто-то может помочь ..Запустите таймер из другой темы в C#

  1. У меня есть форма окна, содержащий кнопку
  2. , когда я нажимаю на эту кнопку я начинаю параметризованные нить
Thread thread1 = new Thread(new ParameterizedThreadStart(execute2)); 
thread1.Start(externalFileParams); 
  1. код внутри потока выполняется очень хорошо
  2. на последней строке этой темы i запускает таймер

.

public void execute2(Object ob) 
{ 
    if (ob is ExternalFileParams) 
    { 
     if (boolean_variable== true) 
      executeMyMethod();//this also executes very well if condition is true 
     else 
     { 
      timer1.enabled = true; 
      timer1.start(); 
      } 
     } 
    } 
} 

5, но клещ событие таймера не выстрелил

Я работаю на VS2008 3.5 рамки. Я перетащил таймер с панели инструментов и установите его Interval 300 также попытался установить Enabled истина/ложь метод timer1_Tick(Object sender , EventArgs e), но его не выпустили

кто-нибудь может предложить то, что я делаю неправильно?

+2

Это маловероятно, что это лучший способ достичь того, что вы хотите - если у вас есть долговременная задача, которая должна обновлять форму с прогрессом, то BackgroundWorker - это хороший способ сделать это. Если вам нужно больше ручного управления, то поток потока (посмотрите на ThreadPool.QueueUserWorkItem) лучше, чем создание собственного потока. –

+0

вам нужно будет вызвать timer.start в потоке своей формы/управления хостом, но это неудобный способ сделать это. Используйте 'Control.BeginInvoke' для вызова соответствующего делегата. – Jodrell

ответ

18


Вы могли бы попытаться запустить таймер таким образом:

Добавить в конструктор формы это:

System.Timers.Timer aTimer = new System.Timers.Timer(); 
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
// Set the Interval to 1 second. 
aTimer.Interval = 1000; 

Добавить этот метод Form1:

private static void OnTimedEvent(object source, ElapsedEventArgs e) 
{ 
    //do something with the timer 
} 

На кнопке мыши события добавьте это:

aTimer.Enabled = true; 

Этот таймер уже имеет резьбу, поэтому нет необходимости запускать новый поток.

3

System.Windows.Forms.Timer работает в однопоточном приложении.

Проверить эту ссылку:

Примечание говорит:

Таймер используется для запуска события в определенного пользователя интервалы времени. Этот таймер Windows предназначен для однопоточной среды , где используются потоки UI для выполнения обработки . Для этого требуется, чтобы код пользователя имел сообщение с сообщением сообщения UI и всегда работал с той же самой нитью или маршал вызова на другой нить.

Подробнее «Замечания», и вы обнаружите, что Microsoft рекомендует использовать этот таймер, синхронизируя его с потоком пользовательского интерфейса.

+0

Существует обходной путь для этого, см. Мой ответ – 321X

+0

Ха-ха, прочитайте мое последнее предложение (он был там час!) :) Спасибо вам! –

+0

Ха-ха :-) Мой плохой! – 321X

7

Это правда, что говорит Матиас Фидемайзер. Но, есть работа вокруг ...

Если у вас есть элемент управления, который является invokable (например, панель состояния), просто вызовите его!

C# Пример кода:

private void Form1_Load(object sender, EventArgs e) 
{ 
    Thread sampleThread = new Thread(delegate() 
    { 
     // Invoke your control like this 
     this.statusStrip1.Invoke(new MethodInvoker(delegate() 
     { 
      timer1.Start(); 
     })); 
    }); 
    sampleThread.Start(); 
} 

private void timer1_Tick(object sender, EventArgs e) 
{ 
    MessageBox.Show("I just ticked!"); 
} 
1

Я хотел бы использовать BackgroundWorker (вместо сырого нити). Основной поток будет подписаться на рабочий RunWorkerCompleted event: событие запускается в вашем основном потоке, когда поток завершается. Используйте этот обработчик событий, чтобы перезапустить таймер.

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