【问题标题】:WinForm Application UI Hangs during Long-Running OperationWinForm 应用程序 UI 在长时间运行期间挂起
【发布时间】:2010-11-16 01:14:02
【问题描述】:

我有一个 Windows 窗体应用程序 我需要使用一个 for 循环,在 2000 - 3000 左右的调用中进行大量远程调用,

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

【问题讨论】:

  • Application.DoEvents() 放入循环中。
  • @i486 - 永远不要打电话给DoEvents()。在代码中引入难以解决的错误是一种邪恶的方式。

标签: c# winforms multithreading


【解决方案1】:

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

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

  1. 您可以将方法调用排队等待在线程池线程上执行(请参阅here):

    ThreadPool.QueueUserWorkItem(new WaitCallback(YourMethod));
    

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

    Task.Factory.StartNew(() => YourMethod());
    

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

    Task.Run(() => YourMethod());
    
  2. 如果您需要进度更新或完成时的通知等内容,您可以使用BackgroundWorker 来更好地控制该方法。将 BackgroundWorker 控件拖到表单上,并将您的方法附加到 dowork 事件。然后在您想运行您的方法时启动工作程序。您当然可以从代码中手动创建 BackgroundWorker,只需记住完成后需要处理它。

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

请记住,对于任何线程,您无法更新 GUI,或从后台线程更改任何 GUI 控件。如果您想在 GUI 上执行任何操作,则必须使用 Invoke(和 InvokeRequired)在 GUI 线程上触发该方法。见here

【讨论】:

    【解决方案2】:
        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.
        }
    

    使用 MethodInvoker 是最简单的方法。

    【讨论】:

      【解决方案3】:

      显然,您需要使用后台线程。我建议你阅读this free e-book

      【讨论】:

        猜你喜欢
        • 2014-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-24
        相关资源
        最近更新 更多