Прогрессбар не будет обновляться с помощью backgroundworker? - PullRequest
1 голос
/ 04 марта 2012

я делаю передачу файлов (сервер-клиент) 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;
    }

Ответы [ 5 ]

1 голос
/ 10 марта 2012

спасибо за [Никола Марковиновича] его ответ был:

строка, которая вызывает ошибку была:

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();
1 голос
/ 04 марта 2012

Вы установили?

worker.WorkerReportsProgress = true;

(либо в коде, либо в окне свойств)


EDIT:

Разве вы не должны читать так

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

вместо чтения data.Length байтов? Так как вы установили data = new byte[fs.Length], файл будет прочитан сразу, а не мелкими частями, что необходимо для постепенного изменения индикатора выполнения.

1 голос
/ 04 марта 2012

Кажется странным, что вы можете присвоить значение элементу управления UI из другого потока без каких-либо исключений.Или , что может быть реальной проблемой.Как первое, что я бы сделал, если код ProgressChanged находится внутри (скажем) WindowsForm класса, напишите так:

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

Примерно так.

0 голосов
/ 04 марта 2012

Ну, это может быть что-то странное, но всегда стоит проверить шаги, которые легко пропустить сначала:

  1. Вы установили для WorkerReportsProgress на BackgroundWorker значение true?
  2. Вы подключили событие ProgressChanged к своему обработчику событий?

Наконец, сравните ваше решение с примером по ссылке ниже - это может напомнить вам о том, что вы забыли сделать: http://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx

0 голосов
/ 04 марта 2012

Фоновый работник работает в новом потоке, поэтому для вызова чего-либо обратно к исходной форме и ее элементам управления (или исходному потоку) потребуется некоторое делегирование для выполнения того, что вы хотите. У меня есть несколько примеров кода, которыми я могу поделиться, но они заняли бы слишком много места здесь на этом сайте. В качестве быстрой помощи, попробуйте часть этой информации с этого сайта.

Фоновый рабочий с делегатами

Конечно, вы всегда можете обратиться в Google для получения дополнительной информации о потоках, делегатах и ​​т. Д. Надеюсь, это поможет.

...