Почему тот же код очищает метку, но успешно изменяет свойство текста кнопки в C #? - PullRequest
0 голосов
/ 12 декабря 2010

Эта ошибка заставила меня потратить 4 часа на отладку совершенно функционального кода вчера вечером.

В основном в некоторых ситуациях c # не обновляет текст текстовой метки, вместо этого он закрывает его.

Я дам вам настройки. Код, который я сейчас пишу, обновляет текстовую метку строками, передаваемыми по сетевому соединению. Так как он приходит из сетевого соединения, он также приходит из фонового потока, поэтому я должен использовать Control.Invoke.

Если: Я посылаю одну или две строки, это обновляет просто отлично. Я говорю ему, чтобы поместить строковые данные в текстовое свойство элемента управления кнопки, он делает это прекрасно. Независимо от того, как быстро это происходит.

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

Вот фактический код, если это поможет.

//oncreate event
public debugScreen() {
 InitializeComponent();

 //used incase guiUdater is ran from the wrong thread
 guiupdate = new guiUpdateDelegate(guiUpdaterFromBackgroundThread);
}

//delegate and creation defininiton for above
private delegate Delegate guiUpdateDelegate(Int32 location, string labelText);
guiUpdateDelegate guiUpdate;


 //updates the form control
public void guiUpdater(string labelName, string labelText) {

 //gets theindex psoition of the control in the form's Control array, returns -1 if not found
 Int32 location = findControlIndexNumberFromName(labelName);

 //if the item is found
 if (location >= 0) {

  //if this function was invoked from the wrong thread
  if (this.Controls[location].InvokeRequired) {

   //invoke the delagate with the function to handle gui updating from the corrext thread.
   //location is the index number of the array in the form's Control array
   //labelText is the new value for the label
   this.Controls[location].Invoke(guiupdate, location, labelText);
  }
  else {

   //if in correct thread just update the bloody thing
   this.Controls[location].Text = labelText; 
  }
 }
 else {
  //if control was not found (location = -1) redo with error on label 9
   guiUpdater("Label9","not found: " + labelName);
 }
}

//updates the text label
private Delegate guiUpdaterFromBackgroundThread(Int32 location, string labelText) {
 Controls[location].Text = labelText;
 return null;
}

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

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

По некоторым советам попытался добавить Application.DoEvents () и Refresh () к соответствующим частям кода. Все еще была та же проблема. Прочитав документацию по методу DoEvents (), я не думаю, что это проблема. Он должен стрелять сам по себе.

Читая документацию, я попытался заменить BeginInvoke, но та же проблема. И BeginInvoke в любом случае выглядит опасно.

1 Ответ

2 голосов
/ 12 декабря 2010

Не уверен, что могу ответить, ПОЧЕМУ это происходит, но если данные поступают так быстро, есть ли смысл обновлять интерфейс для каждого обновления? Кто вообще может это прочитать? Как насчет буферизации, например, поместить последнее обновление в какую-то структуру данных, и когда срабатывает таймер, обновите пользовательский интерфейс с последним значением в этой структуре данных.

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