无法从 BackgroundWorker 中访问表单句柄
Cannot access form handle from within BackgroundWorker
我遇到了一些奇怪的事情。我可以从我的 BackgroundWorker DoWork
方法中访问我的许多表单控件,但是尝试在其中任何一个上获取 Handle
属性 都会给我 "Cross-thread operation not valid".
例如:
private void backgroundWorker1_DoWork(object sender,
System.ComponentModel.DoWorkEventArgs e)
{
var usefulText = textbox1.Text;
var formName = this.Name;
var formHandle = this.Handle; // this line won't work
}
为什么我可以访问除 Handle
属性之外的某些属性(或者看起来如此)?
"Cross-thread operation not valid" InvalidOperationException
是常态。我发现,出于我不知道的原因,某些控件具有可以从错误线程成功调用的成员,但是 the documentation 非常清楚哪些应该起作用:
In addition to the InvokeRequired property, there are four methods on a control that are thread safe to call: Invoke, BeginInvoke, EndInvoke and CreateGraphics
换句话说,你问题中真正的谜团不是为什么你在尝试调用 Handle
属性 getter 时会出现异常。这就是为什么你 没有 得到异常调用 Text
或 Name
getters.
就我个人而言,我觉得这个谜题没那么有趣。最重要的是,如果您需要在 DoWork
事件处理程序中检索 Handle
属性,则需要使用 Control.Invoke()
方法来访问 属性 在 UI 线程上并 return 它返回到工作线程中的代码。或者,在启动工作程序之前检索句柄值,并通过您选择的机制将其提供给 DoWork
事件处理程序。
编辑:
尽管我没有发现这个谜团那么有趣,但我确实继续查看了 referencesource.microsoft.com 网站,我可以看到 the Text
property 被作为显式异常处理"no cross-thread calls" 规则。甚至还有一条注释为 "it's okay to call GetWindowText cross-thread",那里的代码(在 internal WindowText
属性 中)使用 MultithreadSafeCallScope
class 禁用跨线程检查操作的持续时间。
如果这有更好的文档记录(即在 MSDN 本身上),那就太好了,但是你去吧。 :)
我遇到了一些奇怪的事情。我可以从我的 BackgroundWorker DoWork
方法中访问我的许多表单控件,但是尝试在其中任何一个上获取 Handle
属性 都会给我 "Cross-thread operation not valid".
例如:
private void backgroundWorker1_DoWork(object sender,
System.ComponentModel.DoWorkEventArgs e)
{
var usefulText = textbox1.Text;
var formName = this.Name;
var formHandle = this.Handle; // this line won't work
}
为什么我可以访问除 Handle
属性之外的某些属性(或者看起来如此)?
"Cross-thread operation not valid" InvalidOperationException
是常态。我发现,出于我不知道的原因,某些控件具有可以从错误线程成功调用的成员,但是 the documentation 非常清楚哪些应该起作用:
In addition to the InvokeRequired property, there are four methods on a control that are thread safe to call: Invoke, BeginInvoke, EndInvoke and CreateGraphics
换句话说,你问题中真正的谜团不是为什么你在尝试调用 Handle
属性 getter 时会出现异常。这就是为什么你 没有 得到异常调用 Text
或 Name
getters.
就我个人而言,我觉得这个谜题没那么有趣。最重要的是,如果您需要在 DoWork
事件处理程序中检索 Handle
属性,则需要使用 Control.Invoke()
方法来访问 属性 在 UI 线程上并 return 它返回到工作线程中的代码。或者,在启动工作程序之前检索句柄值,并通过您选择的机制将其提供给 DoWork
事件处理程序。
编辑:
尽管我没有发现这个谜团那么有趣,但我确实继续查看了 referencesource.microsoft.com 网站,我可以看到 the Text
property 被作为显式异常处理"no cross-thread calls" 规则。甚至还有一条注释为 "it's okay to call GetWindowText cross-thread",那里的代码(在 internal WindowText
属性 中)使用 MultithreadSafeCallScope
class 禁用跨线程检查操作的持续时间。
如果这有更好的文档记录(即在 MSDN 本身上),那就太好了,但是你去吧。 :)