【问题标题】:Application goes into not responding mode when I switch the window [duplicate]切换窗口时应用程序进入无响应模式[重复]
【发布时间】:2014-10-16 18:14:10
【问题描述】:

我开发了一个 C# 应用程序。在运行时,我切换到系统中的另一个窗口,然后应用程序进入无响应模式,但后台进程正在运行。我在该应用程序中有一个进度条。我需要看看状态,它完成了多少..

            progressBar1.Visible = true;
            progressBar1.Maximum = dt.Rows.Count;
            if (dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    -----
                    ----
                    -----
                    progressBar1.Value = i;
                    if (progressBar1.Value == progressBar1.Maximum - 1)
                    {
                        MessageBox.Show("Task completed");
                        progressBar1.Visible = false;
                    }

                }
             }

【问题讨论】:

  • 最好分享代码..因为有时您会覆盖WinProc 或其他一些事件。
  • WinForms, WPF, SL ?如何/什么线程?
  • 我没有在我的应用程序中使用任何线程概念
  • 但正如@HenkHolterman 所说,您使用的是什么框架? WPF?银光? WinForms?
  • For 循环会在你的应用程序运行时冻结它。您的 for 循环在 UI 线程上运行,此时您使用的框架无关紧要。将工作外包给报告进度的后台工作人员,您将获得所需的结果。

标签: c#


【解决方案1】:

for 循环正在冻结您的 UI 线程,这就是应用程序冻结的原因,因为您在 for 循环中工作时无法重绘 UI。我建议将您的工作卸载到另一个线程并使用后台 Worker:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (worker, result) =>
{
    int progress = 0;

    //DTRowCount CANNOT be anything UI based here
    // this thread cannot interact with the UI
    if (DTRowCount > 0)
    {
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            progress = i;

            -----
            ---- //do some operation, DO NOT INTERACT WITH THE UI
            -----

            (worker as BackgroundWorker).ReportProgress(progress); 
        }
     }
};

worker.ProgressChanged += (s,e) => 
{
    //here we can update the UI
    progressBar1.Value = e.ProgressPercentage
};
worker.RunWorkerCompleted += (s, e) =>
{
    MessageBox.Show("Task completed");
                        progressBar1.Visible = false;
};

worker.RunWorkAsync();

我的目标是将此循环卸载到另一个线程,这将允许您的应用程序继续使用 Windows 消息泵并保持对用户的响应。 Worker 循环并在另一个线程上执行它需要执行的操作,这不能与 UI 或 WindowForms 交互(我假设您正在使用)将抛出错误。

Worker 带着进度报告返回主线程,根据worker.ProgressChanged 事件,您可以从这里访问 UI 并更改进度条值。

当工作人员完成后,它将回调到WorkerThread.RunWorkerCompleted,您可以再次从这里操作 UI。

编辑:代码,WorkerThread.RunWorkerCompleted 到 worker.RunWorkerCompleted

【讨论】:

    猜你喜欢
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 1970-01-01
    • 2015-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多