title: How do I get the GUI thread of winform?
body: <p>I have a winforms app with multiple GUI threads. I want them to be able to access each other's thread objects without having to keep track of that information separately.</p>
  
  <p>Is there a function in .NET that I can feed a winforms control or window object, and get back the thread? Or a function in the API I can pinvoke for the threadID? </p>
  
  <p><em>(please no comments saying I should do it another way... also this is not about cross-thread window operations.)</em></p>
  
  <p>Thanks!</p>
  
  <h2>Edit</h2>
  
  <p>For those of you who for some reason believed my italicized text, congratualations, <strong>you're hired!!</strong> Here is the problem:  </p>
  
  <p>"App is crashing in the wild by locking up totally, that is, it stop responding. Very intermittent, and trying to debug it, it seems to never happen."</p>
  
  <p>So what do do? Install an option in the program that the user can activate under our direction, whereby from another GUI thread in the same app, do a thread.abort on the main GUI thread, then we can look at the call stack in the error log. Viola, found an impossible to debug error in less than a day. (Stop now, it had nothing to do with abusing multithreading:-) </p>
  
  <p>I'll admit I almost didn't ask this, the reason I did was I could see an object reference to the main form, but there wasn't any for its thread. I'm giving Chris Shain the answer a/c it is a quick way, unfortunately when the thread is hanging, I wouldn't be able to do an invoke (it would hang too).  A little more digging revealed the GetWindowThreadProcessId API call. But it's an unmanaged thread ID, apparently there are complications turning that into a managed thread ID.</p>
  
  <p>So I bit the bullet and put in a global reference to the main UI thread. Would have posted it to begin with, but hadn't written it yet.</p>
  
  <p>Now if you'll pardon the VB...</p>
  
  <h3>In main public module/static class:</h3>
  
  <pre><code>Public GUIThread As Threading.Thread
  Sub Main()
      '' //  Create app main window
      ShellForm = New frmShell
      '' // Save main GUI Thread for abort routine
      GUIThread = Threading.Thread.CurrentThread  
      If GetSetting("MyApp", "Testing", "CrashDebug", "False") = "True" Then
              '' //  DO NOT run the pgm. like this normally - with try/catch around
              '' //  Application.Run - or uncaught errors will kill the whole app!!!
          Try
  
              '' // This is the other of the ‘Multiple GUI threads’ I talked
              '' // about in the Orig Post.
              Dim t As New Threading.Thread(AddressOf StartCrashDebug)
              t.Start()
  
              Application.Run(ShellForm)
          Catch ex As Exception
              '' // This error routine passes errors off to another thread which 
              '' // logs them (and also shows messages)
              MyLogError(ex, "CrashDebug - Main Window blew up")
          End Try
      Else
          '' // Normal mode - uncaught errors will get caught by UnhandledException, 
          '' // logged, and Winforms will keep the GUI alive (since we _do_ care 
          '' // more about users than computers right ;-)
          Application.Run(ShellForm)
      End If
  End Sub
  Sub StartCrashDebug()
      Dim f As New frmCrashFinder
      '' // Starting a window like this on a separate thread makes it ‘Another 
      '' // GUI thread’ for winforms, by design
      Application.Run(f)
   End Sub
  </code></pre>
  
  <h3>In ‘aborter’ WinForm:</h3>
  
  <pre><code>Public Class frmCrashFinder 
      Inherits Windows.Form
  
      Private Sub Abort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Abort.Click
          GUIThread.Abort()
      End Sub
  End Class
  </code></pre>