在其他线程上加载 WinForms

发布于 2024-12-02 08:39:19 字数 544 浏览 0 评论 0原文

像许多其他人一样,我需要在其他线程上打开 WinForms。在阅读了很多不同的文章后,我发现这是不可能的,但我的问题是一次可能吗?或者有没有办法实现以下目标?

我正在创建一个带有许多工具窗口的应用程序,这些工具窗口的初始化时间很长(因为许多控件或其他东西无法放在工作线程上),并且当主应用程序启动时并不立即需要这些工具窗口,但我仍然想要向他们展示它们何时可以使用。

这是否可以通过某种方式实现,而不需要其他线程上的 WinForms 功能,而这目前似乎是不可能的?

提前感谢

编辑

大家,感谢您的好文章和提示,但我的错误是没有提供有关我真正的需求之一的更多详细信息。我目前正在使用第三方控件,它使我能够在 MDI 容器中将 WinForms 作为选项卡式窗口打开(我正在使用 Telerik.WinControls.UI.Docking.RadDock)。为此,需要向主 UI 线程(托管 RadDock 的线程)通知新添加的 Winform,以便能够将它们添加到“选项卡式”窗口列表中。这是我不知道如何完成的事情之一,因为这将涉及我在另一个线程上创建的工具窗口之一可以被编组并在主线程上使用。

Like many others, I need to open WinForms on other threads. After reading a lot of different articles, I see that it is not possible but my question is will it be possible at a time or is there a way to achieve the following goal?

I'm creating an application with a lot of tool windows that are long to initialize (because of many controls or other things that cannot be put on worker threads) and these tools windows are not needed immediately when the main application starts but I still want to show them when they'll be ready to be used.

Is this possible to achieve in some way without needing a feature, WinForms on other threads, that seams to be currently impossible now?

thanks in advance

EDIT

All of you, thanks for the good articles and hints but it was my error to not provide any more details about one of my real nead. I'm currently using a third party control that enables me to open WinForms in an MDI container as tabbed windows (i'm using Telerik.WinControls.UI.Docking.RadDock). For this, the Main UI thread, the one that host the RadDock, needs to be informed of newly added Winforms to be able to add them to is "tabbed" window list. This is one of the thing that I do not see how it can be done because this will involve that one of my tool window, created on another thread, can be marshalled and be used on the main thread.

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

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

发布评论

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

评论(2

若能看破又如何 2024-12-09 08:39:19

并不是说您需要在其他线程上显示 WinForm,而是需要使这些表单内的工作异步并实现适当的线程安全同步。我有两篇博客文章适用于此。

两者都适用于 Windows 窗体,并且您可以找到大量有关使 WinForms 异步的文章。

以A为例。

ToolWindowForm form = new ToolWindowForm()) {
form.Show();
// other code

假设您的代码中某处需要显示此工具窗口,但加载时间太长,它会阻止其余代码的执行。好吧,在另一个线程上显示表单可能是实现此目的的一种方法,而且非常有可能。但是,如果您在表单之间进行通信并需要访问控件,那么您将遇到 CrossThreadViolations 和 IllegalCrossThreadCalls 问题,从而使这一情况变得极其复杂。让每个表单背后的工作异步化会更容易、更安全。

编辑
如果必须的话,您可以添加私有成员以将实例存储到表单中,即。

private Form m_MyToolForm = new Form();
private Form m_MyToolForm2 = new Form();

然后在代码中的某个地方。

public void ShowToolForm() {
    Thread thread = new Thread(new ThreadStart(ShowToolFormAsync));
    thread.IsBackground = true;
    thread.Start();
}  

private void ShowToolFormAsync() {
    m_MyToolForm.ShowDialog(); // Blocks on this thread
}

如果您使用的是 .NET 4,您还可以使用任务并行库。

Task.Factory.StartNew(() => m_MyToolForm.ShowDialog());

Its not that you need to show your WinForms on other threads, rather, you need to make the work inside those forms asynchronous and implement proper thread-safe synchronization. I have two blog articles that apply to just this.

Both are for Windows Forms, and there are tons of articles you can find on making your WinForms asynchronous.

A for instance.

ToolWindowForm form = new ToolWindowForm()) {
form.Show();
// other code

Let's say you have this somewhere in your code where you need this tool window to display, but it takes such a long time to load it blocks the rest of your code from execution. Well, showing the form on another thread could be one way to accomplish this, and is very much so possible. What can make this exceedingly complex though is that if you are communicating between forms and need access to controls, you are going to run into CrossThreadViolations and IllegalCrossThreadCalls. Its easier and safer just to make the work behind each form asynchronous.

Edit
If its a must you can add private members to store instances to the forms, ie.

private Form m_MyToolForm = new Form();
private Form m_MyToolForm2 = new Form();

Then somewhere in code.

public void ShowToolForm() {
    Thread thread = new Thread(new ThreadStart(ShowToolFormAsync));
    thread.IsBackground = true;
    thread.Start();
}  

private void ShowToolFormAsync() {
    m_MyToolForm.ShowDialog(); // Blocks on this thread
}

You can also use the Task Parallel Library if you are on .NET 4.

Task.Factory.StartNew(() => m_MyToolForm.ShowDialog());

我似乎不明白这怎么可能。
在不同线程上创建表单和更新表单控件的唯一大问题是,
是你需要一个线程安全的回调,否则你会得到只有创建表单的父线程才能更新 gui 的错误。

有关此线程安全回调以及此跨线程所需的 InvokeRequired 内容的更多信息,请访问:http://msdn.microsoft.com/en-us/library/ms171728%28v=vs.80%29.aspx

I dont seem how this would not be possible.
The only big problem with creating forms and updating form controls over different threads,
is that you will need a thread-safe callback otherwise you will get errors that only the parent thread who created the form is able to update a gui.

More information about this thread-safe callback and the InvokeRequired stuff which is required with this cross-threading is found at : http://msdn.microsoft.com/en-us/library/ms171728%28v=vs.80%29.aspx

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