【问题标题】:progressbar won't update with backgroundworker?进度条不会与后台工作人员一起更新?
【发布时间】:2012-03-03 22:40:04
【问题描述】:

我正在进行文件传输(服务器-客户端)TCP
我已经在寻找类似的问题了..但没有答案对我有用..

ProgressBar 不会随 backgroundworker 更新 .. 我已经搜索了执行此操作的教程 .. 我完全按照这些步骤操作。
发送时和发送文件后表单滞后.. 进度条变为 100%

成功发送的文件发送方法代码工作正常...我的问题只是更新进度条..我该如何解决这个问题??

我在这里调用 (backgroundWorker1.RunWorkerAsync)

public void Send(string destPath)
    {
        if (listView1.Items.Count > 0)
        {
            List<String> job = new List<string>();
            job.Add(listView1.Items[0].ToolTipText);
            job.Add(destPath);
            backgroundWorker1.RunWorkerAsync(job);
        }
    }

DoWork方法

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        List<string> job = (List<string>)e.Argument;
        SendFile(job[0],job[1]);
    }

这是我使用的 SEND 方法 (backgroundWorker1.ReportProgress)

private void SendFile(string srcPath, string destPath)
    {
        string dest = Path.Combine(destPath, Path.GetFileName(srcPath));
        using (fs = new FileStream(srcPath, FileMode.Open, FileAccess.Read))
        {
            try
            {
                long fileSize = fs.Length;
                sizeAll = fileSize;
                long sum = 0;
                int count = 0;
                data = new byte[fs.Length];
                SendCommand("receive<" + dest + "<" + fs.Length.ToString());
                while (sum < fileSize)
                {
                    if (fileSize - sum < packetSize)
                    {
                        count = fs.Read(data, 0, (int)(fileSize - sum));
                        network.Write(data, 0, (int)(fileSize - sum));
                    }
                    else
                    {
                        count = fs.Read(data, 0, data.Length);
                        network.Write(data, 0, data.Length);
                    }
                    fs.Seek(sum, SeekOrigin.Begin);
                    sum += count;
                    sumAll += count;
                    backgroundWorker1.ReportProgress((int)((sum * 100) / fileSize));
                }
                network.Flush();
            }
            finally
            {
                CloseTransfer();
            }
        }
    }

这里是 backgroundWorker1_ProgressChanged

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBarFile.Value= e.ProgressPercentage;
    }

【问题讨论】:

  • progresschanged 方法是否被调用?如果是这样,调用堆栈是什么样的?
  • 你确定传输的文件是一样的吗?因为 fs.Seek 对我来说似乎不合适;它在第一遍后返回到 0 偏移量,并在第二遍中重新读取数据的第一个 packetSize。我认为您无论如何都不需要 Seek,因为文件阅读器将在最后一个读取字节后保持在第一个位置。
  • 而不是 data = new byte[fs.Length];写入数据 = 新字节 [packetSize];并删除 fs.Seek。我相信进度条会起作用。文件传输有效的唯一原因是它是在一个数据包中读取和发送的。
  • 谢谢哥们..我已经修复了..代码是正确的..只是数据包大小的东西..我应该删除我的问题吗??
  • 我是这里的新手,所以我真的不知道,但我认为你不应该删除问题,因为其他人可能会从你的错误中吸取教训 ;-) 并且一定要删除 fs.Seek 因为它会损坏您的文件。

标签: c# winforms progress-bar backgroundworker


【解决方案1】:

看起来很奇怪,您可以从另一个线程为UI 控件分配一个值而不会出现任何异常。或者那个是,可能是,一个真正的问题。 就像我要做的第一件事一样,如果ProgressChanged 的代码在(比如)WindowsForm 类中,请这样写:

private void backgroundWorker1_ProgressChanged(object sender, 
                                                 ProgressChangedEventArgs e)
{
    this.Invoke(new Action(()=>
        progressBarFile.Value= e.ProgressPercentage;
    ));
}

类似的东西。

【讨论】:

  • BackgroundWorker 自动调用 UI 线程上的 ProgressChanged 处理程序。
  • 我读过 backgroundworker.reportprogress 从 UI 线程更新进度条..当我使用教程时它可以工作..只是在我的代码中不起作用
【解决方案2】:

你设置了吗?

worker.WorkerReportsProgress = true;

(在代码或属性窗口中)


编辑:

你不应该这样看书

count = fs.Read(data, 0, packetSize); 

而不是读取data.Length 字节?由于您设置了data = new byte[fs.Length],文件将被一次性读取,而不是小块,这是查看进度条逐渐变化所必需的。

【讨论】:

    【解决方案3】:

    感谢 [Nikola Markovinović] 他的回答是:

    导致错误的行是:

    data = new byte[fs.Length];
    

    修改代码后:

    data = new byte[packetSize];  
    while (sum < fileSize)
    {
         count = fs.Read(data, 0, data.Length);
         network.Write(data, 0, count);
         sum += count;
         backgroundWorker1.ReportProgress((int)((sum * 100) / fileSize));
     }
     network.Flush();
    

    【讨论】:

      【解决方案4】:

      后台工作人员正在一个新线程上闲逛,因此,将任何内容调用回原始表单及其控件(或原始线程)将需要一些委托来完成您想要的。我有几个可以分享的代码示例,但它们会在此站点上占用太多空间。作为快速帮助,请尝试从该站点获取的一些信息。

      Background Worker with Delegates

      当然,您可以随时在 Google 上了解有关线程、委托等的更多信息。希望对您有所帮助。

      【讨论】:

      • 我读过 backgroundworker.reportprogress 从 UI 线程更新进度条..当我使用教程时它可以工作..只是在我的代码中不起作用
      • 它会变得非常有趣。我倾向于避免使用 BackgroundWorker 类,而只使用无聊的多线程。此外,请查看link。无论如何,许多原则保持不变。
      • 我认为这可能是最好的解决方案
      【解决方案5】:

      这可能有点古怪,但总是值得先检查一下容易忽略的步骤:

      1. 您是否将 BackgroundWorker 上的 WorkerReportsProgress 设置为 true?
      2. 您是否已将 ProgressChanged 事件连接到您的事件处理程序?

      最后,只需将您的解决方案与以下链接中的示例进行比较 - 它可能会提醒您一些您忘记做的事情: http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx

      【讨论】:

      • 1 。是的,它是真的。 2.它被迷住了,因为我将它添加为工具箱中的工具 + 当文件发送进度达到 100% 最后我已经检查过该链接,当我使用它时它可以工作,但不能与我的代码一起工作
      猜你喜欢
      • 1970-01-01
      • 2013-02-27
      • 1970-01-01
      • 2010-10-25
      • 2011-10-07
      • 1970-01-01
      • 1970-01-01
      • 2012-06-11
      • 1970-01-01
      相关资源
      最近更新 更多