简体   繁体   English

如何生成一个表单而不阻塞主线程?

[英]How to spawn a form and not block main thread?

I need to spawn a Form that can be used as usual but the main thread must continue doing whatever it is doing afterwards. 我需要产生一个可以照常使用的Form ,但是主线程必须继续执行随后要做的任何事情。 When I try the 2 techniques below I can't use the form: 当我尝试以下2种技巧时,我无法使用该表格:

static class Program
{
    private static void spawnForm1()
    {
        new Form1().Show();
    }

    private static void spawnForm2()
    {
        // solved: use ShowDialog() instead of Show() here
        ThreadPool.QueueUserWorkItem(o => { new Form1().Show(); });
    }

    [STAThread]
    static void Main()
    {
        spawnForm1();
        MessageBox.Show("main thread continues");
        // now anything can happen: background processing or start of main form
        // sleeping is just an example for how the form is unresponsive
        Thread.Sleep(30 * 1000);
    }
}

So how can I spawn a simple Form and continue in main thread ? 那么,如何生成一个简单的Form并在主线程中继续呢? It should respond just like the message box does. 它应该像消息框一样响应。

(I can't use Application.Run(...); and I can't use ShowDialog() if it would block the main thread, also: I'm sorry that I have not much reputation but this is not a noob question, I really need it to be spawned like I tried to explain) (我不能使用Application.Run(...);如果它会阻塞主线程,我也不能使用ShowDialog() ,另外:很抱歉,我的声誉不高,但这不是菜鸟问题,我真的需要像我试图解释的那样生成它)

Don't create a new thread to show the UI. 不要创建新线程来显示UI。 You're in the UI thread and it should be the one showing the form. 您位于UI线程中,应该是显示表单的线程。 Spawn a new thread to do the non-UI work that you want to do instead: 产生一个新线程来执行您要执行的非UI工作:

[STAThread]
static void Main()
{
    Task.Run(()=>
        {
            //do non-UI work here
            Thread.Sleep(30 * 1000);
        });
    Application.Run(new Form1());
}

Your code does not work because there is no message loop. 您的代码不起作用,因为没有消息循环。 You simply must start a message loop for UI elements to function properly. 您仅需启动一个消息循环,UI元素才能正常运行。 That means at some point you must call Application.Run or Form.ShowDialog . 这意味着您必须在某个时候调用Application.RunForm.ShowDialog

I see no reason why you cannot use the entry point thread for the UI and then create a worker thread to do whatever else it is you are wanting to happen while the UI is running. 我认为没有理由为什么不能在UI上使用入口点线程,然后创建一个工作线程来执行UI运行时想要执行的其他任何操作。

[STAThread]
public static void Main()
{
  Task.Run(() => DoOtherStuff());
  Application.Run(new YourForm());
}

In a comment your wrote: 您在评论中写道:

The main window is ran by application like always. 主窗口像往常一样由应用程序运行。 But I need to spawn a window like I described it in both situation existing main window and also without it. 但是我需要在现有主窗口和没有主窗口的情况下生成一个像我描述的窗口。

I am assuming you mean that you want to run Form instances on both the entry point thread and a separate thread. 我假设您的意思是要在入口点线程和单独的线程上运行Form实例。 My advise is to avoid doing this. 我的建议是避免这样做。 It does not work very well. 它不能很好地工作。 There are a lot of strange things that can happen. 可能会发生很多奇怪的事情。 Rethink your design so that there is one and only one UI thread. 重新考虑您的设计,以便只有一个UI线程。 Move any time consuming operations to a worker thread. 将所有耗时的操作移至工作线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM