Как уменьшить задержку интерфейса в C #? - PullRequest
1 голос
/ 06 августа 2009

У меня проблема с задержкой интерфейса в C #.

Поскольку я все еще учусь, будьте терпеливы, пока я объясняю.

Я сузил проблему до моего объекта таймера.

В основном моя программа запрашивает устройство через сокет TCP / IP и выводит его в текстовое поле на экране.

Теперь я опрашиваю устройство на предмет данных каждую секунду, для чего требуется скрыть некоторую логику в объекте таймера, а между тиками происходит следующее:

  1. Увеличить значение.
  2. Создайте 2 строки, которые представляют команду для отправки коробка (инкапсулированная в функцию
  3. Кодировать команду
  4. Отправить команду
  5. Очистить массив байтов
  6. Получите ответ.

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

Ответы [ 3 ]

11 голосов
/ 06 августа 2009

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

Чтобы это исправить, вам просто нужно выполнить работу в фоновом потоке, а затем обновить пользовательский интерфейс в потоке пользовательского интерфейса.

В .NET Framework есть куча разных таймеров, которые работают по-разному: тот, который вы используете, обрабатывает событие таймера в том же потоке, другие работают в фоновых потоках. Проверьте эту статью о различных таймерах .

Вы также можете просто использовать текущий таймер для вызова компонента BackgroundWorker для выполнения работы в фоновом потоке. Основным преимуществом этого является то, что BackgroundWorker будет выполнять работу в фоновом потоке, но будет вызывать событие завершения работы в потоке пользовательского интерфейса, чтобы было проще обновить пользовательский интерфейс, не беспокоясь о том, в каком потоке вы находитесь.

2 голосов
/ 06 августа 2009

Я думаю, это потому, что вы пытаетесь выполнить работу в своем потоке пользовательского интерфейса. Запустите таймер в фоновом рабочем потоке.

1 голос
/ 06 августа 2009

Кажется, что происходит несколько вещей. Во-первых, вы можете делать слишком много в вашем таймере. Как вы строите строку и кодируете команду? Можно ли это сделать один раз за пределами обработчика тиков или каким-либо образом упростить (например, с помощью вызовов String.Format)? На самом деле в .NET доступны три разных таймера с разными разрешениями. Какой таймер вы используете?

Самая большая проблема заключается в том, что ваш интервал составляет 1 секунду. Независимо от того, что это много накладных расходов на обработку. Имейте в виду, что, по большей части, каждый раз, когда достигается интервал и вызывается тиковый обработчик, вы вызываете переключение контекста между потоками. Это связано с некоторыми накладными расходами (с которыми вы ничего не можете поделать), и чем чаще вы переключаете контекст, тем медленнее будет выглядеть ваша производительность.

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