我有一个问题: 我尝试从另一个线程更新标签中的字体颜色,但它失败了,我不知道为什么。
private Color defaultBgColor = Color.Red;
private Color passOkBgColor = Color.LightGreen;
private Color defaultForeColor = Color.FromArgb(255, 255, 255, 255);
private Color passOkForeColor = Color.FromArgb(255, 0, 0, 255);
我的职责是:
private void Func() {
try {
if ( pipeReader != null) {
string msg_strg = String.Empty;
while(true) {
if ( !npsc.IsConnected ) {
npsc.Connect();
Thread.Sleep(500);
continue;
}
while ( (msg_strg = pipeReader.ReadLine()) != null ) { ;
statusLabel.BeginInvoke( (MethodInvoker)(() => {
if ( statusesDict.ContainsKey(msg_strg) )
statusLabel.Text = statusesDict[msg_strg];
else
statusLabel.Text = "!UNKNOWN STATUS!";
if ( msg_strg != "CARDREADER_USER_EXISTS" ) {
this.BackColor = defaultBgColor;
statusLabel.ForeColor = defaultForeColor;
} else {
this.BackColor = passOkBgColor;
statusLabel.ForeColor = passOkForeColor;
}
}) );
statusLabel.Refresh();
Thread.Sleep(300);
}
}
}
} catch ( Exception ex ) {
Log.Instance.Error("Exception: "+ex.Message);
}
}
我该如何解决这个问题?
答案 0 :(得分:1)
您的代码至少存在两个问题。
首先,statusLabel.Refresh
调用应位于BeginInvoke
块内。
其次,BeginInvoke
块使用捕获的变量msg_strg
,它可能在块执行时被修改过。
以下将解决上述问题,尝试查看您的问题(无论是什么)是否已解决:
private void Func() {
try {
if (pipeReader != null) {
Action<string> updateStatus = message =>
{
if (statusesDict.ContainsKey(message))
statusLabel.Text = statusesDict[message];
else
statusLabel.Text = "!UNKNOWN STATUS!";
if (message != "CARDREADER_USER_EXISTS") {
this.BackColor = defaultBgColor;
statusLabel.ForeColor = defaultForeColor;
} else {
this.BackColor = passOkBgColor;
statusLabel.ForeColor = passOkForeColor;
}
statusLabel.Refresh();
};
while(true) {
if (!npsc.IsConnected) {
npsc.Connect();
Thread.Sleep(500);
continue;
}
string msg_str;
while ((msg_strg = pipeReader.ReadLine()) != null) {
statusLabel.BeginInvoke(updateStatus, msg_str);
Thread.Sleep(300);
}
}
}
} catch (Exception ex) {
Log.Instance.Error("Exception: " + ex.Message);
}
}