C# CrossThreadMessaging 读取标签文本
C# CrossThreadMessaging on reading label text
我看过无数主题,但他们都在谈论更新控件的 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);
创建一个像 ExecuteSecure()
一样工作的默认函数会很棒。
你有什么错误?
Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException
当我将光标移动到 this.label_options
的 .Text
值时出现此消息。
编辑 1:
下面的图像显示了错误,尽管代码有效。
最简单的解决方法是改用 Invoke()
。它是同步的(在调用方法 return 之前不会 return),因此您可以依靠它来设置捕获的变量状态。
其中一个版本是简单地修改您现有的方法以调用 Invoke()
而不是 BeginInvoke()
。另一种方法是制作一个通用方法,该方法实际上 returns 传入的值 Func<T>
returns:
private T getExecuteSecure<T>(Func<T> f)
{
if (InvokeRequired)
return (T)Invoke(f);
else
return f();
}
你可以这样使用它:
string value = getExecuteSecure(() => this.label_options.Text);
注意和上面类似,在使用BeginInvoke()
时也可以收到return值。但这很棘手,因为您只能从对 EndInvoke()
的调用中获取它,在您知道调用的委托已完成后执行(这反过来又可以通过 IAsyncResult
returned 找到来自 BeginInvoke()
).
编辑:
至于你在调试器中看到的异常,这是因为当 VS 计算一个 属性 时,它实际上在一个线程中运行 属性 getter。但是该线程不是 属性 的正确线程。因此例外。
我看过无数主题,但他们都在谈论更新控件的 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);
创建一个像 ExecuteSecure()
一样工作的默认函数会很棒。
你有什么错误?
Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException
当我将光标移动到 this.label_options
的 .Text
值时出现此消息。
编辑 1:
下面的图像显示了错误,尽管代码有效。
最简单的解决方法是改用 Invoke()
。它是同步的(在调用方法 return 之前不会 return),因此您可以依靠它来设置捕获的变量状态。
其中一个版本是简单地修改您现有的方法以调用 Invoke()
而不是 BeginInvoke()
。另一种方法是制作一个通用方法,该方法实际上 returns 传入的值 Func<T>
returns:
private T getExecuteSecure<T>(Func<T> f)
{
if (InvokeRequired)
return (T)Invoke(f);
else
return f();
}
你可以这样使用它:
string value = getExecuteSecure(() => this.label_options.Text);
注意和上面类似,在使用BeginInvoke()
时也可以收到return值。但这很棘手,因为您只能从对 EndInvoke()
的调用中获取它,在您知道调用的委托已完成后执行(这反过来又可以通过 IAsyncResult
returned 找到来自 BeginInvoke()
).
编辑:
至于你在调试器中看到的异常,这是因为当 VS 计算一个 属性 时,它实际上在一个线程中运行 属性 getter。但是该线程不是 属性 的正确线程。因此例外。