我之所以问这个问题是因为我遇到了一个异常:
“在一个线程上创建的控件不能作为另一个线程上控件的父级。”
这是我的DoWork事件代码:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var openFile = document.Open(MyFileName);
e.Result = openFile;
}
document
是在父表单创建时初始化的UI控件。在Open
方法期间,document
中的各种属性将被填充。
我尝试更改调用的代码,但仍然存在相同的问题。即,
document.GetType().GetMethod("Open)".Invoke(document, new object[]{MyFileName})
将产生与上述相同的错误。
有什么办法可以操作document
控制?换句话说,如何使上面的代码工作?
编辑:有人建议我使用Control.Invoke
,但它仍然无效(两个线程都挂起)。这是我尝试过的代码:
private delegate bool OpenFile(string filePath);
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
OpenFile oF = new OpenFile(document.Open);
var openFile = Invoke(oF, MyFileName); // it doesn't really matter whether I use BeginInvoke or Invoke, or other Control.Invoke, the end result is the same. Both the main thread hosting the document and the thread that launches the UI hanged.
e.Result = openFile;
}
this.Invoke(document.Open)
。 - Gravitondocument
是什么吗? - GraemeFControl.Invoke()
将完全背离使用 BackgroundWorker 的初衷。BackgroundWorker的目的是通过将长时间运行的任务移动到不同的线程来使UI保持响应性。在BackgroundWorker中使用Invoke()
会启动一个新的线程,该线程立即调用您试图避免的线程。如果Invoke()
是更长过程中的一部分,那么这样做就可以,但是在这里它是整个过程。虽然我怀疑OP是否混淆了文档是不是控件。我们真正需要知道document
对象的确切类型。 - Joel Coehoorn