我看过无数主题,但所有主题都谈到更新控件的<{1}}值而不是检索它的值。
我目前使用以下函数来避免text
,并在调用函数或赋值时正常工作。
cross thread operations
那么,什么有效??
private void ExecuteSecure(Action a)
{
if (InvokeRequired)
BeginInvoke(a);
else
a();
}
您需要什么?
ExecuteSecure(() => this.label_options.Text = "Hello");
创建一个像string value = string.Empty;
ExecuteSecure(() => value = this.label_options.Text);
一样的默认函数会很棒。
你有什么错误?
Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException
当我将光标移动到ExecuteSecure()
.Text
的值时,会显示此消息。
编辑1 : 下面的图像显示错误,尽管代码有效。
答案 0 :(得分:0)
最简单的解决方法是使用Invoke()
代替。它是同步的(在调用的方法返回之前不会返回),因此您可以依赖它来设置捕获的变量状态。
其中一个版本就是简单地修改现有方法,以便调用Invoke()
而不是BeginInvoke()
。另一种方法是创建一个实际返回传入的Func<T>
返回的值的泛型方法:
private T getExecuteSecure<T>(Func<T> f)
{
if (InvokeRequired)
return (T)Invoke(f);
else
return f();
}
你可以这样使用:
string value = getExecuteSecure(() => this.label_options.Text);
请注意,与上面类似,使用BeginInvoke()
时也可以接收返回值。但这很棘手,因为你只能通过调用EndInvoke()
来获取它,在你知道调用的委托已经完成后执行(反过来你通过从{{1}返回的IAsyncResult
找到了})。
修改强>
至于您在调试器中看到的异常,这是因为当VS评估属性时,它实际上在一个线程中运行属性getter。但该线程不是该属性的正确线程。因此例外。