Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the GUI thread of winform?

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.

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?

(please no comments saying I should do it another way... also this is not about cross-thread window operations.)

Thanks!

Edit

For those of you who for some reason believed my italicized text, congratualations, you're hired!! Here is the problem:

"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."

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

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.

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.

Now if you'll pardon the VB...

In main public module/static class:

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

In ‘aborter’ WinForm:

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
like image 355
FastAl Avatar asked Feb 01 '11 19:02

FastAl


People also ask

Is winform still supported?

But Microsoft begs to differ. "We continue to support and innovate in Windows Forms runtime," said Microsoft's Igor Velikorossov last month in announcing what's new for WinForms in .

Can we update UI from thread?

Worker threads However, note that you cannot update the UI from any thread other than the UI thread or the "main" thread. To fix this problem, Android offers several ways to access the UI thread from other threads. Here is a list of methods that can help: Activity.

How do you release a winform?

Click the sign in option and select the checkbox (Sign the Click Once manifests). Go to Security >> select Check Box (Enable Click Once Security Settings). Go to Publish >> select Publishing folder location path and Save. Click "Publish Now" button.

How do I run a WinForms application in the browser?

You can right-click on the icon and then click on the 'Open Web Browser'. A Web browser window will open and your application will be running inside.


2 Answers

All GUI elements in Windows Forms are typically done on a single thread. I strongly recommend avoiding trying to do this any other way.

You can always marshal code to that thread by using Control.Invoke or Control.BeginInvoke with any Control.

If you really want to get the thread's ID (not sure what use this will be..?), you could use:

int GetControlThreadId(Control control)
{
    int threadId;
    control.Invoke( new Action( () => 
       {
           threadId = Thread.CurrentThread.ManagedThreadId;
       }));
    return threadId;
}
like image 105
Reed Copsey Avatar answered Sep 19 '22 11:09

Reed Copsey


If your code is not in a form or control, you can use

if (System.Windows.Forms.Form.ActiveForm.InvokeRequired)
{
    System.Windows.Forms.Form.ActiveForm.Invoke(...);
}
like image 33
Metro Avatar answered Sep 19 '22 11:09

Metro