Обновление индикатора выполнения из фонового потока

Ниже приведен мой фоновый рабочий поток.

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {            
            Thread t1 = new Thread(Thread1);
            t1.Start();
            Thread t2 = new Thread(Thread2);
            t2.Start();
            if (backgroundWorker1.CancellationPending)
            {
                e.Cancel = true;                
            }
        }

Код Thread1 выглядит следующим образом

static void Thread1()
        {
            int nofiles=0;
            int returned = checkforfolderthread(1);
            int startvalue = 0;
            int stopvalue = 5000;
            if (returned == 1)
            {
                nofiles = countfiles();
                startvalue = startvalue + (nofiles - 1) * 1000;
                stopvalue = stopvalue - startvalue;
            }
            repeat(startvalue, stopvalue,1,nofiles-1);

        }

Функция, вызываемая из потока, выглядит следующим образом

static void repeat(int ini, int fin, int threadno, int startadd)
        {
            int i, j;
            for (j = ini; j < ini + fin; j += 1000)
            {
                StringBuilder sb = new StringBuilder();                
                for (i = j; i < j + 1000; i += 100)
                {
                    WebClient wc = new WebClient();
                    string add = System.String.Format("http://www.colourlovers.com/api/colors/new?numResults=100&resultOffset={0}", i);
                    try
                    {
                        string tobeadded = wc.DownloadString(add);                        
                        sb.AppendLine();
                        sb.Append(tobeadded);
                    }

                    catch (Exception)
                    {
                        break;                        
                    }                    
                }                
                string folderpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                string filename = System.String.Format("DownloadPalette\\Thread{0}\\color{1}.xml",threadno,startadd);

                string location = Path.Combine(folderpath, filename);
                File.WriteAllText(location, sb.ToString());
                startadd = startadd + 1;

            }
        }

То, что я хотел бы сделать, это постоянно обновлять индикатор выполнения после завершения каждого цикла for i.

Но я не могу получить доступ к индикатору выполнения из этой функции, работающей в фоновом потоке.

Пожалуйста, помогите мне


person user2546342    schedule 04.07.2013    source источник


Ответы (4)


Вам не хватает этого метода..

// Back on the 'UI' thread so we can update the progress bar
    void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // The progress percentage is a property of e
        progressBar1.Value = e.ProgressPercentage;
    }

Согласно этой ссылке: Демо BackgroundWorker и ProgressBar< /а>

person Olrac    schedule 04.07.2013

Вы должны использовать вызов, как описано здесь: http://msdn.microsoft.com/en-us/library/ms171728(v=vs.80).aspx

person TheDeadSkin    schedule 04.07.2013

Сначала создайте метод для обновления progressbar (создайте его в графическом интерфейсе основного потока):

private void UpdateBar()
{
    //your code to update
}

Затем создайте делегата и передайте ему свой метод (этот код также предназначен для графического интерфейса основного потока):

private delegate void UpdateProgressBarDelegate();
private UpdateProgressBarDelegate UpdateProgressBarDelegate_Object;
UpdateProgressBarDelegate_Object = new UpdateProgressBarDelegate(this.UpdateBar);

Теперь обновите его из другого потока следующим образом:

progressbar.Invoke(UpdateProgressBarDelegate_Object);

Здесь мы вызываем метод delegate object, который вызовет метод UpdateBar в потоке GUI с безопасным вызовом потока.

person Shaharyar    schedule 04.07.2013

Если вам нужно обновить больше, чем просто значение индикатора выполнения, вы можете вызвать метод и проверить, требуется ли вызов. Вызов необходим, если вы хотите получить доступ к объекту пользовательского интерфейса из отдельного потока.

private void updateProgress(object sender, int count, int total)
{
    if (base.InvokeRequired)
    {
        base.Invoke(new ProcessCountHandler(this.updateProgress), new object[] { sender, count, total });
    }
    else if (count <= this.progressBar1.Maximum)
    {
        this.progressBar1.Value = count;
        this.CompletedCount.Text = count.ToString("N0") + " of " + total.ToString("N0");
    }
}
person Marlon Navas    schedule 04.07.2013