Run multiple UI Threads
Asked Answered
F

4

9

Skip to the bottom for the question; this is just some extra info

I am using a component (GeckoFX) to render some websites, well fine, yet it can only be used in a Windows Form; as it has to bind to a WinForms object that can be drawn. Because all the WinForms are running in the same thread, I can only use one GeckoFX instance at a time; so I decided to create a 'worker class' in the form of a WinForm, and add all the logic in there. The form doesn't require to communicate with the main form.

Now I can fire up 10 windows, and they will eventually work, but every new form will wait before all the other forms have handled all their GeckoFX events, as you cannot use multiple instances on one thread. Furthermore, the browser has to be on a UIThread. So:

Is it possible to create multiple UI Threads (one for each form)?

I have seen someone doing it ([edit: removed 'bad' link]), yet no one ever got his code samples working. The guy who got it working originally used some form of custom message pumping to do this kind of things, but I have no clue how to achieve something like that.

Frankforter answered 14/10, 2009 at 14:48 Comment(0)
C
9

I don't think that what you ask is really what you want but creating a message pump per thread is easy, you just have to call Application.Run once per thread.

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Thread t1 = new Thread(Main_);
        Thread t2 = new Thread(Main_);

        t1.Start();
        t2.Start();

        t1.Join();
        t2.Join();
    }

    static void Main_()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}
Corry answered 14/10, 2009 at 23:1 Comment(2)
Was kind of what I was looking for, yet GeckoFX now is complaining about memory access violations, so I'll just keep on running my single thread for now :-)Frankforter
Note that you don't have to create a form to run a message loop -- just use the parameterless Application.Run() on a thread.Eustasius
W
3

Use Application.DoEvent().
or
Create multiply threading forms:

    Thread form2Thread;
    Form2 form2;

    private void Form1_Load(object sender, EventArgs e)
    {
        form2Thread = new Thread(RunForm2);
        form2Thread.SetApartmentState(ApartmentState.STA);
        form2Thread.Name = "Form2 Thread";   // looks nice in Output window
        form2Thread.Start();
    }

    public void RunForm2()
    {
        form2 = new Form2();
        Application.Run(form2);
    }
Wenonawenonah answered 14/10, 2009 at 22:51 Comment(2)
That's not what non-modal means programmersheaven.com/2/FAQ-WinForm-Modal-Non-ModalHindorff
got something up already, but didn't work as creating new UIthreads from one UIThread gives strange behavior.Frankforter
E
3

GeckoFx doesn't require a form.

GeckoWebBrowser wb = new GeckoWebBrowser();
wb.CreateControl(); //<-- the magic lays here!
wb.DocumentCompleted += delegate{ MessageBox.Show(wb.DocumentTitle); };
wb.Navigate("http://mysite.com");
Eardrop answered 14/12, 2010 at 6:2 Comment(0)
A
1

Seems like it is possible.

I took backgrounder, opened TestApp, and created a new Form1 on thread/message pump #2:

private void button2_Click(object sender, EventArgs e) {
    helper.Background(() => {
        Form1 form2 = new Form1();
        form2.Show();
    });
}

The second window responds to mouse clicks etc.

Haven't actually verified if everything looks right, the freebie Visual Studio Express Edition I'm using is missing the "Threads" debug window, ahem. So I'm a bit in the dark. It seems to work, though. Let me know :-).

Atal answered 14/10, 2009 at 22:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.