首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Windows窗体线程和事件- ListBox更新迅速,但进度栏遇到巨大延迟

Windows窗体线程和事件- ListBox更新迅速,但进度栏遇到巨大延迟
EN

Stack Overflow用户
提问于 2008-08-15 09:19:04
回答 6查看 1.6K关注 0票数 4

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

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

代码语言:javascript
运行
复制
public delegate void ImportProgressEventHandler(object sender, ImportProgressEventArgs e);
public static event ImportProgressEventHandler importProgressEvent;

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

代码语言:javascript
运行
复制
Thread dataProcessingThread = new Thread(new ParameterizedThreadStart(ImportController.ImportData));
dataProcessingThread.Name = "Data Importer: Data Processing Thread";
dataProcessingThread.Start(settings);

ImportProgressEvent args包含一个字符串消息、一个用于进度条的最大int值和一个当前进度int值。Windows窗体为该事件添加了以下内容:

代码语言:javascript
运行
复制
ImportController.importProgressEvent += new ImportController.ImportProgressEventHandler(ImportController_importProgressEvent);

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

代码语言:javascript
运行
复制
    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);
            }

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

代码语言:javascript
运行
复制
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似乎更新得非常快,但进度条直到批处理接近完成时才会移动。怎么回事?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2008-08-15 10:07:06

@John

谢谢你的链接。

@Will

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

关于雪撬锤子,你是对的。但是,事实证明,我的问题毕竟是在屏幕和椅子之间。我似乎有一批不相关的数据,它的外键记录比其他批多得多,只是碰巧在这个过程的早期被选中,这意味着currentProgress在整整10秒内都不会得到++'d。

@All

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

票数 0
EN

Stack Overflow用户

发布于 2008-08-15 09:38:37

也许您可以尝试一下BackgroundWorker组件。它使线程处理变得更容易。示例如下:

  • BackgroundWorker Threads and Supporting Cancel
  • Using the BackgroundWorker Component in .NET 2 applications
  • BackgroundWorker Sample
票数 2
EN

Stack Overflow用户

发布于 2008-08-15 09:58:16

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12095

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档