Murhaf Sousli
Murhaf Sousli

Reputation: 13296

progressbar won't update with backgroundworker?

im making file transfer (Server-Client) 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.
the form lags while sending and after the file sent.. the progressbar goes to 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)

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

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)

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

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

Upvotes: 1

Views: 2559

Answers (5)

Murhaf Sousli
Murhaf Sousli

Reputation: 13296

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

Upvotes: 1

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112269

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? 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.

Upvotes: 1

kaj
kaj

Reputation: 5251

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?
  2. Have you hooked up the ProgressChanged event to your event handler?

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

Upvotes: 0

CSmanic
CSmanic

Reputation: 78

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.

Upvotes: 0

Tigran
Tigran

Reputation: 62248

Seems strange the you're able to assign a value to the a UI control from another thread without getting any exception. 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:

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

Something like this.

Upvotes: 1

Related Questions