C#:并行形式、多线程和“应用程序中的应用程序”

本文关键字:应用程序 多线程 并行 | 更新日期: 2023-09-27 18:36:53

首先,我需要的是 - n WebBrowser-s,每个在自己的窗口中做自己的工作。用户应该能够看到所有命令,或者只看到其中一个(或没有),并对每个执行命令。有一个主窗体,没有浏览器,这个窗体包含我的应用程序的控制面板。

关键功能是,每个浏览器都登录到安全的网页,并且需要尽可能长时间地保持登录状态。好吧,我已经做到了,但我担心我的方法有问题。

问题是:

下面的代码是否有效,或者更确切地说是可能导致问题的令人讨厌的黑客:

internal class SessionList : List<Session> {
    public SessionList(Server main) {
        MyRecords.ForEach(record => {
            var st = new System.Threading.Thread((data) => {
                var s = new Session(main, data as MyRecord);
                this.Add(s);
                Application.Run(s);
                Application.ExitThread();
            });
            st.SetApartmentState(System.Threading.ApartmentState.STA);
            st.Start(record);
        });
    }
    // some other uninteresting methods here...
}

这是怎么回事?会话继承自表单,因此它创建一个表单,将 Web 浏览器放入其中,并具有在网站上操作的方法。WebBrowser需要在STA线程中运行,因此我们为每个浏览器提供了一个。其中最有趣的部分是 Application.Run(s) .它使新创建的表单具有活力和交互性。下一个Application.ExitThread()在浏览器窗口关闭并释放其控件后调用。主应用程序保持活动状态以执行其余的清理作业。

当用户选择"退出"或"关机"选项时 - 首先浏览器线程结束,因此调用Application.ExitThread()。这一切都有效,但是在我可以找到的任何地方都可以读到有关"主 GUI 线程"的信息 - 在这里 - 我创建了许多 GUI 线程。我使用 Invoke() 使用线程安全方法处理主窗体和新窗体(会话)之间的通信。这一切都有效,所以是对还是错?

在一个应用程序中多次使用Application.Run()是否一切正常?:)丑陋的黑客还是正常的做法?如果我从会话表单线程启动 Web 浏览器,此代码将死亡。它打败了我为什么。但是,如果我从任何其他线程启动 WebBrowser(通过更改其 Url 属性),它可以工作。我想知道更多在这样的应用程序中到底发生了什么。但最重要的是 - 我想知道我对"应用程序中的应用程序"的想法是否正常。

我不确定Application.Run()到底是做什么的。没有它,在新线程中创建的表单将死去响应。我怎么可能多次打电话Application.Run()?它似乎完全符合它应该做的事情,但对我来说似乎有点未记录的功能。我几乎可以肯定,崩溃是由WebBrowser组件本身引起的(因为它不是完全"托管"和"本机"的)。但也许是别的什么。

C#:并行形式、多线程和“应用程序中的应用程序”

在一个应用程序中多次使用 Application.Run() 是否一切正常? :)丑陋的黑客还是正常的做法?

两者中的一些;) 这是完全可以接受的,因为它会像你期望的那样运作,但这并不完全是一种"正常的做法"。

我不确定Application.Run()到底是做什么的。

Application.Run基本上做了几件事。 首先,它将属性SynchronizationContext安装到线程中,以便 Windows 窗体正常运行。 然后,它会在该线程中启动 Windows 消息处理,该线程处理来自 Windows 进入线程的所有消息。 这就是允许表单正常工作的原因。

这样做没有什么特别的错误,但这不是标准做法。 鉴于您的设计目标,我确实质疑仅启动单独的进程而不是尝试在单独的线程中运行每个操作是否更好。