无法从 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 时会出现异常。这就是为什么你 没有 得到异常调用 TextName 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 本身上),那就太好了,但是你去吧。 :)