为什么相同的代码会将标签空白但成功更改C#中按钮的文本属性?

时间:2010-12-12 16:32:23

标签: c# winforms multithreading controls label

这个错误让我花了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;
}

它没有做任何必要的事情,只是调试输出,并且由于它在按钮上更新得很好,我知道数据正在通过。所以,如果这是这个问题的限制,我可以忍受它。但是我很好奇发生了什么。看起来它可能会在更新标签的过程中切断。就像它消隐标签,然后应用新文本,但只是在新文本部分之前停在中间。

如果是这种情况,如果我不把它扼杀在萌芽状态,它可能会警告一个讨厌的bug。

在一些建议上尝试将Application.DoEvents()和Refresh()添加到代码的相关部分。还是有同样的问题。在阅读了DoEvents()方法的文档后,我不认为这是一个问题。它应该自己开火。

阅读文档我试过替换BeginInvoke,但同样的麻烦。而且,无论如何,BeginInvoke看起来很危险。

1 个答案:

答案 0 :(得分:2)

我不确定为什么会发生这种情况,但如果数据进展如此之快,那么更新每次更新的UI是否有用?无论如何谁能读它?如何缓冲它,比如将最新的更新放在某种数据结构中,当某个计时器滴答时,用该数据结构中的最新值更新UI。