当尝试从主MMI线程以外的其他线程调用文本框时,我碰巧遇到此跨线程错误。我已经明白为什么会发生这种情况。我希望你对我解决这个问题的方式有所了解。 我正在使用它,因为我讨厌在整个代码中添加委托声明。
private void SetText(string text)
{
if (textBox1.InvokeRequired)
{
this.Invoke(new Action<string>(SetText), new object[]{ text });
}
else
{
this.textBox1.Text = text;
}
}
这是正确的方法吗? 是否有更好更短的方式?
答案 0 :(得分:0)
你所拥有的一切都没有错。如果您不想进行递归调用,可以在Invoke()
调用中抛出一个匿名代理:
private void SetText(string text)
{
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
this.textBox1.Text = text;
});
}
else
{
this.textBox1.Text = text;
}
}
答案 1 :(得分:0)
这是关于唯一的方法,尽管我会做两处修改:
1)使用MethodInvoker以便您可以省略Func或Action转换,但继续使用递归以便您不会复制代码。
2)添加一个返回到调用块,以便你没有else块。我宁愿添加额外的行而不是额外的缩进。
private void SetText(string text)
{
if (textBox1.InvokeRequired)
{
this.Invoke((MethodInvoker) delegate { SetText(text); });
return;
}
this.textBox1.Text = text;
}
第二个想法你可以有一个实用程序方法,它接受一个Action进行检查,而实际的逻辑总是在lambda内。
private static void InvokeIfRequired(bool required, Action action) {
// NOTE if there is an interface which contains InvokeRequired
// then use that instead of passing the bool directly.
// I just don't remember off the top of my head
if (required) {
this.Invoke((MethodInvoker) delegate { action(); });
return;
}
action();
}
private void SetText(string text)
{
InvokeIfRequired(textBox1.InvokeRequired, () => {
this.textBox1.Text = text;
});
}