title: How to add Control to Control from another thread, without Invoke?
body: <p>I created an app which uses plugins. Plugin contains ToolStrip which I want to add to main ToolStrip Container Panel (in Form1 class). This is easy <code>container.TopToolStripPanel.Controls.Add(plugin.PluginToolStrip;</code>, but if I want to run plugins code in separated thread, then it's not as easy. (I use multithreading for easy way to unload plugin, I only need to kill plugin thread, and remove ToolStrip from main form)</p>
  
  <p>I disabled <code>CheckForIllegalCrossThreadCalls = false;</code> to allow not-using Invoke void. But when I want to run <code>container.TopToolStripPanel.Controls.Add(plugin.PluginToolStrip);</code> from another Thread then program throws <code>ArgumentException</code> and says that I can't do it.</p>
  
  <p>So, how can I create plugins architecture with possibility to kill plugins threads? (I want to give user possibility of easy way of management plugins)</p>
  
  <p>I decompilled System.Windows.Forms.dll to see where it throws that exception and I saw:</p>
  
  <pre><code>            /// &lt;summary&gt;Adds the specified control to the control collection.&lt;/summary&gt;
              /// &lt;param name="value"&gt;The &lt;see cref="T:System.Windows.Forms.Control" /&gt; to add to the control collection. &lt;/param&gt;
              /// &lt;exception cref="T:System.Exception"&gt;The specified control is a top-level control, or a circular control reference would result if this control were added to the control collection. &lt;/exception&gt;
              /// &lt;exception cref="T:System.ArgumentException"&gt;The object assigned to the &lt;paramref name="value" /&gt; parameter is not a &lt;see cref="T:System.Windows.Forms.Control" /&gt;. &lt;/exception&gt;
              public virtual void Add(Control value)
              {
                  if (value == null)
                  {
                      return;
                  }
                  if (value.GetTopLevel())
                  {
                      throw new ArgumentException(SR.GetString("TopLevelControlAdd"));
                  }
                  if (this.owner.CreateThreadId != value.CreateThreadId)
                  {
                      throw new ArgumentException(SR.GetString("AddDifferentThreads")); //here!
                  }
                  /* [...] */
              }
  </code></pre>
  
  <p>then I think that if i can change <code>this.owner.CreateThreadId</code>, then I will be able to pass this if (<code>if (this.owner.CreateThreadId != value.CreateThreadId)</code>), and program will not throw exception. On line 6315 i saw this code:</p>
  
  <pre><code>internal int CreateThreadId
          {
              get
              {
                  if (this.IsHandleCreated)
                  {
                      int num;
                      return SafeNativeMethods.GetWindowThreadProcessId(new HandleRef(this, this.Handle), out num);
                  }
                  return SafeNativeMethods.GetCurrentThreadId();
              }
          }
  </code></pre>
  
  <p>we have only get, and it's internal :(</p>
  
  <p>What can I do? Do you have any suggestions? Thanks and sorry for my bad English...</p>