跨线程操作
Cross-thread operation
我在尝试从主 MMI 线程以外的其他线程调用文本框时碰巧遇到了这个跨线程错误。我已经明白为什么它 happens.I 想要你对我解决这个问题的方式发表意见。
我使用它是因为我讨厌在整个代码中添加委托声明。
private void SetText(string text)
{
if (textBox1.InvokeRequired)
{
this.Invoke(new Action<string>(SetText), new object[]{ text });
}
else
{
this.textBox1.Text = text;
}
}
这是正确的方法吗?
有没有更好更短的方法?
你得到的没有问题。如果你不想进行递归调用,你可以在 Invoke()
调用中抛出一个匿名委托:
private void SetText(string text)
{
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
this.textBox1.Text = text;
});
}
else
{
this.textBox1.Text = text;
}
}
这是唯一的方法,尽管我会做两个改变:
1) 使用 MethodInvoker 以便您可以省略 Func 或 Action 转换,但继续使用递归以避免重复代码。
2) 在调用块中添加一个return,这样就没有else 块了。我宁愿多加一行也不愿多加缩进。
private void SetText(string text)
{
if (textBox1.InvokeRequired)
{
this.Invoke((MethodInvoker) delegate { SetText(text); });
return;
}
this.textBox1.Text = text;
}
转念一想,您可以使用一个实用程序方法来执行检查,而实际逻辑将始终在 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;
});
}
我在尝试从主 MMI 线程以外的其他线程调用文本框时碰巧遇到了这个跨线程错误。我已经明白为什么它 happens.I 想要你对我解决这个问题的方式发表意见。 我使用它是因为我讨厌在整个代码中添加委托声明。
private void SetText(string text)
{
if (textBox1.InvokeRequired)
{
this.Invoke(new Action<string>(SetText), new object[]{ text });
}
else
{
this.textBox1.Text = text;
}
}
这是正确的方法吗? 有没有更好更短的方法?
你得到的没有问题。如果你不想进行递归调用,你可以在 Invoke()
调用中抛出一个匿名委托:
private void SetText(string text)
{
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
this.textBox1.Text = text;
});
}
else
{
this.textBox1.Text = text;
}
}
这是唯一的方法,尽管我会做两个改变:
1) 使用 MethodInvoker 以便您可以省略 Func 或 Action 转换,但继续使用递归以避免重复代码。
2) 在调用块中添加一个return,这样就没有else 块了。我宁愿多加一行也不愿多加缩进。
private void SetText(string text)
{
if (textBox1.InvokeRequired)
{
this.Invoke((MethodInvoker) delegate { SetText(text); });
return;
}
this.textBox1.Text = text;
}
转念一想,您可以使用一个实用程序方法来执行检查,而实际逻辑将始终在 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;
});
}