C# WinForm应用程序UI在长时间运行操作期间挂起

C# WinForm应用程序UI在长时间运行操作期间挂起,c#,winforms,multithreading,C#,Winforms,Multithreading,我有一个windows窗体应用程序 我需要使用一个for循环,它有大量的远程调用,大约2000-3000个调用 在执行for循环时,我失去了对表单和表单控件的控制,因为它变成了一个大进程,有时会显示“没有响应”,但如果我等了很长时间,它又回来了,我想我需要使用一些线程模型来实现这一点,有什么想法吗,我如何继续解决这个问题?显然,您需要使用后台线程。我建议您阅读。您需要在后台线程上执行长时间运行的操作 有几种方法可以做到这一点 您可以将方法调用排队以在线程池线程上执行(请参阅): 在.NET 4.

我有一个windows窗体应用程序 我需要使用一个for循环,它有大量的远程调用,大约2000-3000个调用


在执行for循环时,我失去了对表单和表单控件的控制,因为它变成了一个大进程,有时会显示“没有响应”,但如果我等了很长时间,它又回来了,我想我需要使用一些线程模型来实现这一点,有什么想法吗,我如何继续解决这个问题?

显然,您需要使用后台线程。我建议您阅读。

您需要在后台线程上执行长时间运行的操作

有几种方法可以做到这一点

  • 您可以将方法调用排队以在线程池线程上执行(请参阅):

    在.NET 4.0中,您可以使用:

    在.NET 4.5及更高版本中,您可以(而且应该,而不是
    TaskFactory.StartNew()
    )使用
    Task.Run()

  • 如果您需要诸如进度更新或完成时的通知之类的内容,那么您可以使用更大的控件来控制该方法。将BackgroundWorker控件拖到窗体上,并将方法附加到dowork事件。然后,当您想要运行您的方法时,只需启动worker。当然,您可以从代码中手动创建BackgroundWorker,但请记住,完成后需要处理它

  • 为你的工作创建一个全新的线程。这是最复杂的,并且不是必需的,除非您需要对线程进行真正细粒度的控制。如果您想了解这一点,请参阅课程上的MSDN页面

  • 请记住,对于任何线程化的对象,都无法更新GUI,或从后台线程更改任何GUI控件。如果要在GUI上执行任何操作,必须使用Invoke(和invokererequired)在GUI线程上触发该方法。看


    使用MethodInvoker是最简单的方法。

    Application.DoEvents()
    放入循环。@i486-永远不要调用
    DoEvents()
    。在代码中引入难以解决的bug是一种邪恶的方式。
    ThreadPool.QueueUserWorkItem(new WaitCallback(YourMethod));
    
    Task.Factory.StartNew(() => YourMethod());
    
    Task.Run(() => YourMethod());
    
        private voidForm_Load(object sender, EventArgs e)
        {
            MethodInvoker mk = delegate
            {
                //your job
            };
            mk.BeginInvoke(callbackfunction, null);
        }
    
        private void callbackfunction(IAsyncResult res)
        {
            // it will be called when your job finishes.
        }