Отзывчивый пользовательский интерфейс в форме окна доступа к данным устройства - PullRequest
0 голосов
/ 30 января 2012

У меня есть приложение C # windows form, которое запрашивает данные с подключенного устройства. В настоящее время я запускаю System.Timer.Timer, который запускается каждые 20 мс и получает данные из подключенного инструмента. Это работает нормально, но, конечно, пользовательский интерфейс перестает отвечать на запросы обновлений счетчиков данных, конечных результатов вычислений для данных и т. Д. И т. Д. Я также отображаю данные в паре окон OpenGL, так что происходит довольно много.

_timer1 = new System.Timers.Timer{
Interval = Convert.ToDouble(txtElapse.Text),
Enabled = true};    
_timer1.Elapsed += Timer1Elapsed;

Затем я использую, а затем аннулирую форму, чтобы перерисовать OpenGL, и именно здесь выполняются все мои вычисления и т. Д.

Мой вопрос связан с многопоточностью, в какой момент или к какому объекту я применяю логику потока? Сам таймер? Если я делаю это, я не могу отладить, он просто сидит там. Я провел немало исследований, связанных с ThreadPools, Backgroundworker, Thread и т. Д., Но ничего для этой ситуации не сделал, поскольку считаю (ошибочно?), Что таймер по умолчанию работает в своем собственном потоке.

1 Ответ

1 голос
/ 30 января 2012

Хорошее эмпирическое правило заключается в том, что все, что занимает больше времени или может занять больше 50 мс, должно быть асинхронным.Варианты многопоточности зависят от используемой целевой платформы, потому что в .NET 2-3.5 у вас есть стандартные асинхронные шаблоны (начало, конец, вызов, обратные вызовы), а в .NET 4 - библиотека параллельных задач.

BackgroundWorker является оболочкой для асинхронной операции.Так что это будет соответствовать требованиям вашей операции.Учитывая, что вы сказали, что провели немало исследований, я не буду вдаваться в подробности.

Вы также можете раскрутить поток и выполнить потокобезопасных вызовов в пользовательский интерфейс.

public void StartFooAsync() {
    Thread thread = new Thread(new ThreadStart(DoFooAsync));
    thread.IsBackground = true;
    thread.Start();
}

private void DoFooAsync() {
    while (m_Running) {
        // Do something
        Thread.Sleep(20ms); // Make the thread wait your 20ms
    }
}

Вы также можете использовать параллельную библиотеку задач в .NET4 .

...