запустить таймер из другого потока в c # - PullRequest
13 голосов
/ 20 апреля 2011

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

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

.

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

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

Ответы [ 4 ]

18 голосов
/ 20 апреля 2011


Вы можете попробовать запустить таймер следующим образом:

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

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;

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

6 голосов
/ 20 апреля 2011

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

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

Пример кода 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!");
}
3 голосов
/ 20 апреля 2011

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

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

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

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

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

0 голосов
/ 20 апреля 2011

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

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