2

是否可以有多个线程形式作为 MDIChild?我有一个 MdiChild 形式的 ActiveX 控件,它可能会占用大量处理 CPU,并且希望通过使用下面的示例代码使一个控件不会影响另一个控件。但是行 frmDoc.MdiParent = Me 会引发跨线程异常。

Dim frmDoc As MDIChild
Dim newThread As New Thread(
    Sub()
        frmDoc = New MDIChild
        frmDoc.MdiParent = Me '<- this line throws cross threading exception.
        Application.Run(frmDoc)
    End Sub
)
newThread.IsBackground = True
newThread.SetApartmentState(ApartmentState.STA)
newThread.Start()

引发 System.InvalidOperationException 未处理:

Message=Cross-thread operation not valid: 
  Control 'FormMdiApp' accessed from a thread other than the thread it was created on.
Source=System.Windows.Forms
4

3 回答 3

3

GUI 元素只能在主事件循环中初始化和访问。您可以异步或在后台线程中处理繁重的计算。

于 2012-09-20T04:11:50.410 回答
1

尝试 BackgroundWorker http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.95).aspx

执行 DoWork 事件中的所有繁重操作,并使用 ProgressChanged/RunWorkerCompleted 事件更新 UI 元素。

于 2012-09-20T04:14:46.647 回答
0

关于如何实现这一点的可用选项

刚刚找到一篇很好的 msdn 支持文章How To Create Windows in a Multithreaded Application

当在一个线程中创建父窗口并且在另一个线程中创建子窗口时,创建窗口可以强制执行隐式AttachThreadInput ()。在具有父子关系的单独线程中创建(或设置)窗口时,将附加输入队列。

可以在 演练中找到更多信息:通过在其自己的线程上显示每个 Windows 窗体来支持 COM 互操作

有人问了类似的问题Spawn a new thread to open a new window and close it from another thread

但是,幸运的是,这些都没有关于子窗体的任何内容。

更新:刚刚在演练代码中发现了错误;但总的来说,这个样本有一些好主意。

于 2012-09-30T00:50:54.583 回答