运行多个 UI 线程

发布于 2024-08-07 13:20:27 字数 471 浏览 11 评论 0原文

跳到问题底部;这只是一些额外的信息

我正在使用一个组件(GeckoFX)来渲染一些网站,很好,但它只能在 Windows 窗体中使用;因为它必须绑定到可以绘制的 WinForms 对象。因为所有 WinForm 都在同一个线程中运行,所以我一次只能使用一个 GeckoFX 实例;所以我决定以 WinForm 的形式创建一个“工作类”,并在其中添加所有逻辑。该表单不需要与主表单进行通信。

现在我可以启动 10 个窗口,它们最终会工作,但每个新表单都会在所有其他表单处理完所有 GeckoFX 事件之前等待,因为您不能在一个线程上使用多个实例。此外,浏览器必须位于 UIThread 上。那么:

是否可以创建多个 UI 线程(每个表单一个)?

我见过有人这样做([编辑:删除了“坏”链接]),但没有人获得他的代码示例在职的。让它工作的人最初使用某种形式的自定义消息泵来做这种事情,但我不知道如何实现类似的事情。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

娇妻 2024-08-14 13:20:27

我不认为您所要求的确实是您想要的,但为每个线程创建消息泵很容易,您只需为每个线程调用一次 Application.Run 即可。

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

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());
    }
}
古镇旧梦 2024-08-14 13:20:27

使用Application.DoEvent()。

创建多线程形式:

    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);
    }

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);
    }
萌酱 2024-08-14 13:20:27

GeckoFx 不需要表格。

GeckoWebBrowser wb = new GeckoWebBrowser();
wb.CreateControl(); //<-- the magic lays here!
wb.DocumentCompleted += delegate{ MessageBox.Show(wb.DocumentTitle); };
wb.Navigate("http://mysite.com");

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");
转瞬即逝 2024-08-14 13:20:27

似乎是有可能的。

我使用了 backgrounder,打开 TestApp,并在线程/消息泵 #2 上创建了一个新的 Form1 :

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

第二个窗口响应鼠标点击等。

尚未实际验证是否一切正常,我正在使用的免费 Visual Studio Express 版本缺少“线程”调试窗口,咳咳。所以我有点摸不着头脑。不过,这似乎有效。让我知道:-)。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文