2010-03-23 1 views
1

В надстройке VSTO, которую я разрабатываю, мне нужно выполнить метод с определенной задержкой. Сложная часть заключается в том, что для выполнения метода может потребоваться от 0,1 с до 1 секунды. Я в настоящее время использую System.Timers.Timer так:C# - Повторение вызова метода с использованием таймеров

private Timer tmrRecalc = new Timer(); 

    // tmrRecalc.Interval = 500 milliseconds 

    private void tmrRecalc_Elapsed(object sender, System.Timers.ElapsedEventArgs e){ 

     // stop the timer, do the task 
        tmrRecalc.Stop();      
        Calc.recalcAll(); 
        
        // restart the timer to repeat after 500 ms 
        tmrRecalc.Start(); 
    } 

Который в основном начинается, возникает событие 1 истечь, после чего он будет остановлен для произвольной задачи длины выполняется. Но поток пользовательского интерфейса, кажется, вешает трубку в течение 3-5 секунд между каждой задачей.

У таймеров есть время прогрева? Неужели это так долго для его первого (и последнего) истечения?

Какой тип таймера я использую вместо этого?

+0

Работает ли функция 'Calc.recalcAll()' с любыми элементами управления пользовательского интерфейса? – dan

+0

Да, это необходимо. –

ответ

2

Вместо использования таймера я рекомендую выполнять вычисления в другом потоке (создайте нить) и используя Thread.Sleep (миллисекунды), чтобы спать между интервалами. Это сработало для меня замечательно.

+0

Никогда не делал многопотоков раньше. Как я создаю поток и могу ли он легко работать с потоком пользовательского интерфейса? (Не просите меня писать маршалов для каждого метода, который я хочу назвать) –

+0

Да, он будет работать с потоками пользовательского интерфейса, вам просто нужно вызвать BeginInvoke в основном потоке, если вы собираетесь обновить интерфейс основного потока. Это всего лишь 2 линии. .Net имеет очень хорошую поддержку для потоковой передачи, в основном вам нужно только указать имя метода для нового объекта Thread (System.Threading.Thread). В эти дни многопроцессорных вычислений вы не можете обойтись без потоков. Я уже начал изучать параллельную библиотеку задач в новой .Net 4, чтобы я мог наилучшим образом использовать несколько процессоров в своем будущем программном обеспечении. –

2

Возможно, ваши расчеты занимают больше времени, чем вы думали. Таймеры не имеют никакой разминки.

Есть ли причина, по которой вы не можете использовать фоновый поток, возможно, объект BackgroundWorker для выполнения вычислений без необходимости использования таймера?

+0

Если я вызову метод «Calc.recalcAll» вручную, используя кнопку на интерфейсе ленты, она выполняется точно так же, как я сказал раньше, от 0,1 с до 1 секунды за звонок, чтобы выполнить полностью. Может ли BackgroundWorker работать с потоком пользовательского интерфейса? –

+0

Честно говоря, я сам не использовал BackgroundWorkers. Но вы можете легко создать новые объекты Thread, установить делегат ThreadStart, а затем запустить их. Когда ваши расчеты обновляются, вы можете отключить их функции пользовательского интерфейса, но да, вы должны их маршалировать. Это легко - либо вызов функции фонового вызова Invoke на любые элементы управления в пользовательском интерфейсе, либо ваши элементы управления защищены блоком InvokeRequired. Вы можете найти последний шаблон в Google или здесь, на SO. – Tesserex

+0

Чтобы быть ясным, это технически не имеет значения, какой контроль вы вызываете Invoke on. Все, что будет в вашем пользовательском интерфейсе. Все, что имеет значение, это то, что объект был создан в потоке, в котором работает цикл сообщений (который был создан Application.Run). – Tesserex