c# - 进度条在 winform 中卡住

标签 c# multithreading winforms progress-bar

我正在尝试处理一个包含 10,000 多行的文件并将其存储在数据库中。处理一个文件通常需要 2-3 分钟,所以我想显示 progressbar

程序的问题是我的 progressbar 控件以及 processForm 中的 label 根本不显示。我已经用谷歌搜索了几个小时,但我仍然无法解决这个问题。

enter image description here

这是我的代码 btnApplyEOD_Click 处理文件的方法

private void btnApplyEOD_Click(object sender, EventArgs e)
{
    string url = txtEODReport.Text;
    if (url != null)
    {
        using (var file = new System.IO.StreamReader(url))
        {
            int i = 0;
            linesInEOD = File.ReadAllLines(url).Count();

            if (backgroundWorkerEOD.IsBusy != true)
            {
                progressForm = new ProgressForm();
                progressForm.Show();
                backgroundWorkerEOD.RunWorkerAsync();
            }

            while ((line = file.ReadLine()) != null)
            {
                string[] splitLines = line.Split('~');
                switch (splitLines[0])
                {
                    case "01":
                    {
                        BOID = splitLines[1].Trim() + splitLines[2].Trim();
                        break;
                    }
                    .........
                }
                i++;
                currentLine = i;
            }
        }
        ...........
        bindToGridView();
    }

}

我使用了BackgroundWorkerBackgroundWorker_DoWork方法的代码如下:

private void backgroundWorkerEOD_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker workerEOD = sender as BackgroundWorker;
    //for (int i = 1; i <= 10; i++)             //usually works but useless for this scenario
    //{
    //    workerEOD.ReportProgress(i * 10);
    //    System.Threading.Thread.Sleep(500);
    //}

    for (int i = 1; i <= linesInEOD; i++)       // doesn't work at all but it will give accurate progressbar increase 
    {
        workerEOD.ReportProgress(100 * currentLine / linesInEOD);
    }
}

BackgroundWorker_ProgressChanged 方法:

private void backgroundWorkerEOD_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressForm.Message = "In progress, please wait... " + e.ProgressPercentage.ToString() + "%";
    progressForm.ProgressValue = e.ProgressPercentage;
}

最佳答案

您正在 UI 线程中执行耗时任务,因此卡住 UI 是正常的。我认为你应该把你的耗时任务放在 BackgroundWorkerDoWork 中,并在需要时调用 backgroundWorker1.RunWorkerAsync(); :

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    this.PerformTimeConsumingTask();
}

public void PerformTimeConsumingTask()
{
    //Time-Consuming Task

    //When you need to update UI
    progressForm.Invoke(new Action(() =>
    {
        progressForm.ProgressValue = someValue;
    }));
}

如果您使用的是 .Net 4.5,您还可以考虑使用 async/await模式。

关于c# - 进度条在 winform 中卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32957254/

相关文章:

c# - 如何在多线程中从TargetInitationException中优雅地恢复?

java - volatile 变量未读取其更新值

c# - 从指定时间开始秒表

c# - 从 c# winforms 应用程序将输出写入控制台

c# - 将文件从 PC 复制到 Windows Mobile 设备的好方法是什么?

c# - 使用 WCF 的 REST 服务 - 可选的查询字符串参数?

c# - 如何在非托管 C++ dll 中查找调用方程序集名称

c# - 使用 Linq 对 Gridview 进行分页

java并发: CopyOnWriteArrayList strategy

c# - var this.Parent as STP2Main 更好的语法