Ending Two Threads with Progressbar in C#

Asked

Viewed 694 times

0

I’m making a ProgressBar file conversions, each converted file is updated to ProgressBar with a percentage of total files to be converted.

I read in a tutorial how to do the ProgressBar, work with Threads with her and here’s my problem:

When cancelling the form ProgressBar (I have a button for that) form is indeed terminated, but the Conversion keeps running, (I noticed this because these conversions go to a specific folder that keeps getting new files).

I need to know How to interrupt them both Threads at the same time:

Code

private void bgwProgresso_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i < ListaCandidatos.Count; i++)
    {
        Arquivo arq = new Arquivo();
        arq.Linhas = Importadora.LerArquivo(ListaCandidatos[i]);
        arq.SetNome(arq.Linhas);
        arq.Endereco = ListaCandidatos[i];
        arq.SemanaEntrega = arq.GetSemanaEntrega(ListaCandidatos[i]);
        arq.Validacao = true;
        this.EnderecosConvertidos.Add(conv.ProcessarOC(arq));
        int percent = (int)(((double)(i + 1) / (double)(ListaCandidatos.Count - 1)) * 100);
        this.bgwProgresso.ReportProgress(percent);
        pbProgresso.CreateGraphics().DrawString(percent.ToString() + "%", new Font("Arial", (float)8.25, FontStyle.Regular), Brushes.Black, new PointF(pbProgresso.Width / 2 - 10, pbProgresso.Height / 2 - 7));

    }
    if (bgwProgresso.CancellationPending)
    {
        e.Cancel = true;
        return;
    }
    bgwProgresso.ReportProgress(100);

}

private void bgwProgresso_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    System.Media.SystemSounds.Beep.Play();
    this.Close();
}

private void btnCancelar_Click(object sender, EventArgs e)
{
    if (bgwProgresso.IsBusy)
    {
        bgwProgresso.CancelAsync();
    }
    lblStatus.Text = "Cancelado";
    this.Close();
}

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

I thought it might be the if at the end of the Loop and include it in the code, but also did not work and still threw me a Exception in the ProgressChanged

Code

private void bgwProgresso_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < ListaCandidatos.Count; i++)
{
    Arquivo arq = new Arquivo();
    arq.Linhas = Importadora.LerArquivo(ListaCandidatos[i]);
    arq.SetNome(arq.Linhas);
    arq.Endereco = ListaCandidatos[i];
    arq.SemanaEntrega = arq.GetSemanaEntrega(ListaCandidatos[i]);
    arq.Validacao = true;
    this.EnderecosConvertidos.Add(conv.ProcessarOC(arq));
    int percent = (int)(((double)(i + 1) / (double)(ListaCandidatos.Count - 1)) * 100);
    this.bgwProgresso.ReportProgress(percent);
    pbProgresso.CreateGraphics().DrawString(percent.ToString() + "%", new Font("Arial", (float)8.25, FontStyle.Regular), Brushes.Black, new PointF(pbProgresso.Width / 2 - 10, pbProgresso.Height / 2 - 7));
    this.pbProgresso.BeginInvoke(
        new Action(() =>
        {
            if (bgwProgresso.CancellationPending)
            {
                e.Cancel = true;
                return;
            }
        }
        ));
}
bgwProgresso.ReportProgress(100);    
}

private void bgwProgresso_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    System.Media.SystemSounds.Beep.Play();
    this.Close();
}

private void btnCancelar_Click(object sender, EventArgs e)
{
    if (bgwProgresso.IsBusy)
    {
        bgwProgresso.CancelAsync();
    }
    lblStatus.Text = "Cancelado";
    this.Close();
}

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

I was thrown this Exception:

Error

Invalid threaded operation: 'pbProgress' control accessed from one thread that is not the one in which it was created

Updating:

Contrary to what I’ve been suggested, I need to terminate both Threads, not just Progressbar visualization.

  • Are you using Backgroundworker right? Have you set up Backgroundworker to support cancellation by interrupting the process/thread? Example: ** bgw.Workersupportscancellation = true; ** Run a test to see if it solves

  • Yes @Renan, it was previously set to true , I used a step-free progress bar, and it worked that way.

1 answer

0


It was necessary to implement some actions regarding the cancel button, follow revised and functional code:

    for (int i = 0; i < ListaCandidatos.Count; i++)
        {
            Arquivo arq = new Arquivo();
            arq.Linhas = Importadora.LerArquivo(ListaCandidatos[i]);
            arq.SetNome(arq.Linhas);
            arq.Endereco = ListaCandidatos[i];
            arq.SemanaEntrega = arq.GetSemanaEntrega(ListaCandidatos[i]);
            arq.Validacao = true;
            if (bgwProgresso.CancellationPending)
            {
                e.Cancel = true;
                bgwProgresso.ReportProgress(0);
                return;
            }
            this.EnderecosConvertidos.Add(conv.ProcessarOC(arq));
            lblStatus.BeginInvoke(
                new Action(() =>
            {
                lblStatus.Text = string.Format("Convertendo {0} de {1}...", i, ListaCandidatos.Count);
            }
                ));
            int percent = (int)(((double)(i + 1) / (double)(ListaCandidatos.Count)) * 100);
            this.bgwProgresso.ReportProgress(percent);
        }
        bgwProgresso.ReportProgress(100);
    }

    //o que fazer no fim.
    private void bgwProgresso_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Cancelled)
        {
            System.Media.SystemSounds.Beep.Play();
            this.Close();
        } else if(e.Error != null)
        {
            MessageBox.Show("Erro desconhecido");
            this.Close();
        }
        else
        {
            this.Close();
        }
    }

    private void btnCancelar_Click(object sender, EventArgs e)
    {
        if (bgwProgresso.IsBusy)
        {
            bgwProgresso.CancelAsync();
        }
        lblStatus.Text = "Cancelando...";
    }

    private void bgwProgresso_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        if (e.ProgressPercentage >= 100)
        {
            bgwProgresso.Dispose();
            this.Close();
        }
        else
        {
            pbProgresso.Value = e.ProgressPercentage;
            pbProgresso.CreateGraphics().DrawString(e.ProgressPercentage.ToString() + "%", new Font("Arial", (float)8.25, FontStyle.Regular), Brushes.Black, new PointF(pbProgresso.Width / 2 - 10, pbProgresso.Height / 2 - 7));
        }
    }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.