4

我们的团队正在创建一个新的招聘工作流程系统来替换旧的。我的任务是将旧数据迁移到新模式中。我决定通过创建一个小型 Windows 窗体项目来做到这一点,因为架构完全不同,直接的 TSQL 脚本不是一个合适的解决方案。

完成这项工作的主要密封类“ImportController”声明了以下委托事件:

public delegate void ImportProgressEventHandler(object sender, ImportProgressEventArgs e);
public static event ImportProgressEventHandler importProgressEvent;

主窗口使用新线程在该类中启动一个静态方法:

Thread dataProcessingThread = new Thread(new ParameterizedThreadStart(ImportController.ImportData));
dataProcessingThread.Name = "Data Importer: Data Processing Thread";
dataProcessingThread.Start(settings);

ImportProgressEvent 参数携带字符串消息、进度条的最大 int 值和当前进度 int 值。Windows 窗体订阅该事件:

ImportController.importProgressEvent += new ImportController.ImportProgressEventHandler(ImportController_importProgressEvent);

并使用它自己的委托以这种方式响应事件:

    private delegate void TaskCompletedUIDelegate(string completedTask, int currentProgress, int progressMax);

private void ImportController_importProgressEvent(object sender, ImportProgressEventArgs e)
            {
                this.Invoke(new TaskCompletedUIDelegate(this.DisplayCompletedTask), e.CompletedTask, e.CurrentProgress, e.ProgressMax);
            }

最后更新进度条和列表框:

private void DisplayCompletedTask(string completedTask, int currentProgress, int progressMax)
        {
            string[] items = completedTask.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string item in items)
            {
                this.lstTasks.Items.Add(item);
            }

            if (currentProgress >= 0 && progressMax > 0 && currentProgress <= progressMax)
            {
                this.ImportProgressBar.Maximum = progressMax;
                this.ImportProgressBar.Value = currentProgress;
            }
        }

问题是 ListBox 似乎更新得很快,但进度条永远不会移动,直到批处理几乎完成?是什么赋予了 ?

4

6 回答 6

2

也许你可以试试 BackgroundWorker 组件。它使线程更容易。这里的例子:

于 2008-08-15T09:38:36.613 回答
0

也许超出了范围,但有时它有助于Application.DoEvents();使 gui 部件对用户输入做出反应,例如按下状态栏对话框上的取消按钮。

于 2008-08-15T09:58:15.797 回答
0

您是否有机会运行 Windows Vista?我在一些与工作相关的应用程序中注意到了完全相同的事情。不知何故,进度条“动画”时似乎有延迟。

于 2008-08-15T10:01:57.550 回答
0

@约翰

感谢您的链接。

@将要

线程池没有任何好处,因为我知道它只会产生一个线程。线程的使用纯粹是为了在 SQL Server 受到读写冲击的同时拥有响应式 UI。这当然不是一个短命的线程。

关于大锤,你是对的。但是,事实证明我的问题毕竟是在屏幕和椅子之间。我似乎有一批不寻常的数据,其外键记录比其他批次多得多,并且恰好在过程的早期被选中,这意味着 currentProgress 在 10 秒内没有得到 ++'d。

@全部

感谢您的所有输入,它让我思考,这让我在代码的其他地方寻找,这导致了我的谦逊时刻,我再次证明错误通常是人为的:)

于 2008-08-15T10:07:06.447 回答
-1

您确定 UI 线程在所有这些过程中都在自由运行吗?即它没有被阻塞在加入或其他等待中?这就是我的样子。

使用 BackgroundWorker 的建议是一个很好的建议 - 绝对优于尝试通过大量 Refresh/Update 调用来解决问题。

BackgroundWorker 将使用池线程,这比创建自己的短期线程更友好。

于 2008-08-15T09:50:34.517 回答
-1

线程池没有任何好处,因为我知道它只会产生一个线程。线程的使用纯粹是为了在 SQL Server 受到读写冲击的同时拥有响应式 UI。这当然不是一个短命的线程。

好的,我很感激,很高兴你发现了你的错误,但是你看过 BackgroundWorker 吗?它几乎与您正在做的事情完全相同,但是以标准化的方式(即没有您自己的委托)并且不需要创建新线程 - 这两者都是(可能很小,但可能仍然有用)的优点。

于 2008-08-15T10:20:01.663 回答