Запустить таймер из разных потоков в С#

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

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

.

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 to 300, также попытался установить Enabled true/false метод timer1_Tick(Object sender , EventArgs e), но его не запускается

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

Ответы

Ответ 1


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

Добавьте в конструктор формы следующее:

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
 }

В случае нажатия кнопки click:

aTimer.Enabled = true;

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

Ответ 2

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

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

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

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!");
}

Ответ 3

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

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

Примечание:

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

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

Ответ 4

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