简体   繁体   English

进度条不会与后台工作者一起更新?

[英]progressbar won't update with backgroundworker?

im making file transfer (Server-Client) TCP 我正在进行文件传输(服务器 - 客户端)TCP
i've already looked for same questions like this one .. but no answer worked for me .. 我已经找过像这样的问题..但没有答案对我有用..

ProgressBar doesn't update with backgroundworker .. i've searched for tutorials to do this .. and i exactly followed the steps. ProgressBar没有用backgroundworker更新..我已经搜索了教程来做这个..我完全按照步骤。
the form lags while sending and after the file sent.. the progressbar goes to 100% 发送时和发送文件后表单滞后..进度条转到100%

The file sent succesfully the send method code works fine... my problem just with updating the progressbar .. how do i fix that ?? 成功发送的文件发送方法代码工作正常...我的问题只是更新进度条..我如何解决?

Here i call ( backgroundWorker1.RunWorkerAsync ) 我在这里打电话( 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 Method DoWork方法

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

here's the SEND method which i use ( backgroundWorker1.ReportProgress ) 这是我使用的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();
            }
        }
    }

and here is backgroundWorker1_ProgressChanged 这里是backgroundWorker1_ProgressChanged

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

Seems strange the you're able to assign a value to the a UI control from another thread without getting any exception. 似乎很奇怪,您能够从另一个线程向UI控件分配值,而不会遇到任何异常。 Or that is, may be, a real issue. 或者 ,这可能是一个真正的问题。 Like a first thing I would do, if the code of ProgressChanged is inside (say) WindowsForm class, write like this: 就像我要做的第一件事,如果ProgressChanged的代码在(比如说) WindowsForm类中,请像这样写:

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

Something like this. 像这样的东西。

Did you set? 你准备好了吗?

worker.WorkerReportsProgress = true;

(Either in code or in the properties window) (在代码中或在属性窗口中)


EDIT: 编辑:

Shouldn't you be reading like this 你不应该这样读书吗

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

instead of reading data.Length bytes? 而不是读取数据。 data.Length字节? Since you set data = new byte[fs.Length] the file will be read all at once, instead of in little pieces, which is required in order to see the progress bar change progressively. 由于您设置了data = new byte[fs.Length]因此将立即读取文件,而不是小块,这是为了逐步查看进度条所需的。

thanks for [Nikola Markovinović] his answer was: 感谢[尼古拉·马尔科维诺维奇],他的回答是:

the line that causes the error was : 导致错误的行是:

data = new byte[fs.Length];

after correcting the code : 纠正代码后:

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();

The background worker is dorking around on a new thread, therefore, calling anything back to the original form and its controls (or original thread) will require some delegation to accomplish what you desire. 后台工作人员在新线程上闲逛,因此,将任何内容调用回原始表单及其控件(或原始线程)都将需要一些委派才能完成您想要的操作。 I have several code examples that I can share but they would take up far too much space here on this site. 我有几个代码示例,我可以分享,但他们会在这个网站上占用太多空间。 As a quick assistance, try some of this information from this site. 作为快速帮助,请尝试从此站点获取一些此类信息。

Background Worker with Delegates 有代表的背景工作者

Of course, you can always Google for more regarding threading, delegates, etc. I hope that helps. 当然,您可以随时通过Google了解有关线程,代表等的更多信息。我希望有所帮助。

Well it may be something quirky but always worth checking the steps its easy to overlook first: 好吧,这可能有些古怪,但总是值得首先检查容易忽略的步骤:

  1. Have you set WorkerReportsProgress on the BackgroundWorker to true? 您是否已将BackgroundWorker上的WorkerReportsProgress设置为true?
  2. Have you hooked up the ProgressChanged event to your event handler? 您是否已将ProgressChanged事件连接到事件处理程序?

Finally just compare your solution to a sample at the link below - it may remind you of something you've forgotten to do: http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx 最后,只需将您的解决方案与下面链接中的示例进行比较 - 它可能会让您想起您忘记做的事情: http//msdn.microsoft.com/en-us/library/cc221403%28v=vs.95% 29.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM