2

Is it possible to have multiple threaded forms as MDIChild? I have an ActiveX control in MdiChild form that can take a lot of processing CPU, and would like to make that one control will not influence another control by using sample code below. But line frmDoc.MdiParent = Me throws cross threading exception.

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()

Throws System.InvalidOperationException was unhandled:

Message=Cross-thread operation not valid: 
  Control 'FormMdiApp' accessed from a thread other than the thread it was created on.
Source=System.Windows.Forms
walter
  • 843
  • 2
  • 14
  • 35

3 Answers3

3

GUI elements must be initialized and accessed in the main event loop only. You can process heavy calculations asynchronously or in background threads.

Andrey Atapin
  • 7,745
  • 3
  • 28
  • 34
  • 1
    It is possible to have multiple forms each with their own thread and message loop, but I don't think it will work with MDI children. – Blorgbeard Sep 20 '12 at 04:13
  • 1
    @Blorgbeard, is this reasonable to do so? I've never faced multiple forms in multiple threads. Can you show examples? Thanks. – Andrey Atapin Sep 20 '12 at 16:02
  • Yes, it's feasible. Basically you do what OP is doing, except not with MDI forms. In a new (STA) thread, you create a form, then pass it to Application.Run, which sets up a new event-loop for you. You need to be careful to Invoke any cross-thread calls, but it works. – Blorgbeard Sep 23 '12 at 20:55
  • For example Google Chrome runs each tab in a separate process – walter Sep 30 '12 at 00:53
  • @walter: Google Chrome also doesn't run on WinForms. – rossisdead Sep 30 '12 at 02:41
1

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

Perform all the heavy opration in DoWork event and use the ProgressChanged/RunWorkerCompleted event to update the UI elements.

Sonal Satpute
  • 490
  • 3
  • 8
0

Available options on how to implement this

Just found a good msdn support article How To Create Windows in a Multithreaded Application

Creating a window can force an implicit AttachThreadInput(), when a parent window is created in one thread and the child window is being created in another thread. When windows are created (or set) in separate threads with a parent-child relationship, the input queues are attached.

More information can be found on Walkthrough: Supporting COM Interop by Displaying Each Windows Form on Its Own Thread

Similar question was asked Spawn a new thread to open a new window and close it from a different thread

But, anfortunatelly non of those have anything about child forms.

Update: Just have found bugs in Walkthrough code; but overall this sample has some good ideas.

Community
  • 1
  • 1
walter
  • 843
  • 2
  • 14
  • 35