Why does the same code blank a label but successfully change the text property of a button in C#?
This bug tricked me into spending 4 hours debugging perfectly functional code last night.
Basically in certain situations c# isn't updating a text label's text, instead it blanks it.
I'll give you the setup. The code I'm writing currently updates a text label with strings streamed over a network connection. Since it's coming in from a networking connection, it's also coming in from a background thread so I have to use Control.Invoke.
If: I send one or two strings it updates just fine. I tell it to put the string data on a button control's text property it does it just fine. No matter how fast it comes in.
However it doesn't display on labels if it comes in too fast. The label text is blanked instead, but occasionally I'll see brief flashes of data. I've tried reading the label text property from other controls and it's actually blanked of text, not just displaying nothing. Stopping the data stream leaves it blank.
Here's the actual code if that helps.
//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);
guiUpdateDelegat开发者_StackOverflow中文版e 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;
}
It doesn't do anything essential, just debug output, and since it updates just fine on buttons I know the data is getting through. So if this is the limit of this problem I can live with it. However I'm pretty curious what's going. It looks like it might be cutting off in the middle of updating the label. Like it's blanking the label, and then applying new text, but just stopping in the middle before the new text part.
If this is the case it could be a warning of a nasty bug later if I don't nip it in the bud.
On some advice tried adding Application.DoEvents(), and Refresh() to relevant parts of the code. Still had the same problem. After reading the documentation for the DoEvents() method, I don't think it's an issue of that. It should be firing on it's own.
Reading the documentation I tried substituting BeginInvoke, but same trouble. And BeginInvoke looks dangerous anyway.
Not sure I can answer WHY this is happening, but if the data is coming in so fast, is there any use in updating the UI for every update? Who can read it anyway? How about buffering it, like putting the lastest update in some kind of data structure, and when some timer ticks, update the UI with the latest value in that data structure.
精彩评论