Winforms 如何在调用无参数应用程序的线程中运行代码。run()?

Winforms 如何在调用无参数应用程序的线程中运行代码。run()?,winforms,devexpress,Winforms,Devexpress,我想在一个单独的线程上通过WiForm函数呈现一个图表 我试着做如下事情: Form yourForm; Thread thread = new Thread( () => { yourForm = new HiddenForm(); Application.Run(yourForm); }); thread.ApartmentState = ApartmentState.STA; thread.Start(); yourForm.Invoke(chartRenderi

我想在一个单独的线程上通过WiForm函数呈现一个图表

我试着做如下事情:

Form yourForm;
Thread thread = new Thread( () =>
{
     yourForm = new HiddenForm();
     Application.Run(yourForm);
});
thread.ApartmentState = ApartmentState.STA;
thread.Start();
yourForm.Invoke(chartRenderingFunction)

而且要确保隐藏的内容永远不会显示出来。然而,我不需要那个隐藏的形式,还有一个无参数的形式。但是,如果我运行它,它不会返回。所以我的问题是,一旦我在线程中调用Application.Run(),我该如何向其中注入代码?

好吧,实际上您确实需要那个隐藏窗口。让代码在该线程上运行的唯一方法。必须有人调用PostMessage(),这需要一个窗口句柄。您的Invoke()调用进行该调用。您确实应该使用BeginInvoke(),如果要等待调用完成,那么启动线程没有意义

使用Application.Run(yourForm)将使窗口可见。您可以通过重写HiddenForm类中的SetVisibleCore()方法来阻止其可见:

protected override void SetVisibleCore(bool value) {
    if (!this.IsHandleCreated) {
        CreateHandle();
        value = false;
        ThreadReady.Set();
    }
    base.SetVisibleCore(value);
}
CreateHandle()调用是确保创建窗口以便处理PostMessage()通知所必需的。还要注意添加的AutoResetEvent(ThreadReady),您必须在调用线程的Start()方法后调用ThreadReady.WaitOne(),以确保BeginInvoke()调用正常工作。处理表单以使线程退出或调用Application.exit()


最后但并非最不重要的一点是,在该线程上使用非平凡控件时要非常小心。图表控件肯定没有显示。例如,如果该控件使用SystemEvents类,您将遇到长期问题。您的工作线程将使其在该工作线程上引发事件。但在图表打印出来后,它就不复存在了。现在,您将在任意线程池线程上触发事件,非常讨厌。死锁是一种常见的灾难,在锁定工作站时特别容易触发。

实际上,您确实需要隐藏窗口。让代码在该线程上运行的唯一方法。必须有人调用PostMessage(),这需要一个窗口句柄。您的Invoke()调用进行该调用。您确实应该使用BeginInvoke(),如果要等待调用完成,那么启动线程没有意义

使用Application.Run(yourForm)将使窗口可见。您可以通过重写HiddenForm类中的SetVisibleCore()方法来阻止其可见:

protected override void SetVisibleCore(bool value) {
    if (!this.IsHandleCreated) {
        CreateHandle();
        value = false;
        ThreadReady.Set();
    }
    base.SetVisibleCore(value);
}
CreateHandle()调用是确保创建窗口以便处理PostMessage()通知所必需的。还要注意添加的AutoResetEvent(ThreadReady),您必须在调用线程的Start()方法后调用ThreadReady.WaitOne(),以确保BeginInvoke()调用正常工作。处理表单以使线程退出或调用Application.exit()


最后但并非最不重要的一点是,在该线程上使用非平凡控件时要非常小心。图表控件肯定没有显示。例如,如果该控件使用SystemEvents类,您将遇到长期问题。您的工作线程将使其在该工作线程上引发事件。但在图表打印出来后,它就不复存在了。现在,您将在任意线程池线程上触发事件,非常讨厌。死锁是一种常见的灾难,在锁定工作站时特别容易触发。

实际上,您确实需要隐藏窗口。让代码在该线程上运行的唯一方法。必须有人调用PostMessage(),这需要一个窗口句柄。您的Invoke()调用进行该调用。您确实应该使用BeginInvoke(),如果要等待调用完成,那么启动线程没有意义

使用Application.Run(yourForm)将使窗口可见。您可以通过重写HiddenForm类中的SetVisibleCore()方法来阻止其可见:

protected override void SetVisibleCore(bool value) {
    if (!this.IsHandleCreated) {
        CreateHandle();
        value = false;
        ThreadReady.Set();
    }
    base.SetVisibleCore(value);
}
CreateHandle()调用是确保创建窗口以便处理PostMessage()通知所必需的。还要注意添加的AutoResetEvent(ThreadReady),您必须在调用线程的Start()方法后调用ThreadReady.WaitOne(),以确保BeginInvoke()调用正常工作。处理表单以使线程退出或调用Application.exit()


最后但并非最不重要的一点是,在该线程上使用非平凡控件时要非常小心。图表控件肯定没有显示。例如,如果该控件使用SystemEvents类,您将遇到长期问题。您的工作线程将使其在该工作线程上引发事件。但在图表打印出来后,它就不复存在了。现在,您将在任意线程池线程上触发事件,非常讨厌。死锁是一种常见的灾难,在锁定工作站时特别容易触发。

实际上,您确实需要隐藏窗口。让代码在该线程上运行的唯一方法。必须有人调用PostMessage(),这需要一个窗口句柄。您的Invoke()调用进行该调用。您确实应该使用BeginInvoke(),如果要等待调用完成,那么启动线程没有意义

使用Application.Run(yourForm)将使窗口可见。您可以通过重写HiddenForm类中的SetVisibleCore()方法来阻止其可见:

protected override void SetVisibleCore(bool value) {
    if (!this.IsHandleCreated) {
        CreateHandle();
        value = false;
        ThreadReady.Set();
    }
    base.SetVisibleCore(value);
}
CreateHandle()调用是确保创建窗口以便处理PostMessage()通知所必需的。还要注意添加的AutoResetEvent(ThreadReady),您必须在调用线程的Start()方法后调用ThreadReady.WaitOne(),以确保BeginInvoke()调用正常工作。处理表单以使线程退出或调用Application.exit()

最后但并非最不重要的一点是,在该线程上使用非平凡控件时要非常小心。图表c