简体   繁体   中英

Stop the background worker from other project

I have two project in one solution. One is form (exe), and one is class (dll).

I have a backgroundworker (in form project) like this:

private void CalculateBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{          
        try
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            if (worker.CancellationPending == true)
            {
                e.Cancel = true;
            }
            else
            {
                Grav_Fluid.Rule.Processing_Controller.SpectralAnalysisFormController spectralAnalysisFormController = new Grav_Fluid.Rule.Processing_Controller.SpectralAnalysisFormController();
                outputDataTable = spectralAnalysisFormController.Proccess(inputDataTable, double.Parse(DistanceIntervalTextBox.Text), worker);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

this is what happen in class project (dll):

public DataTable Proccess(DataTable inputDataTable, double ITV, System.ComponentModel.BackgroundWorker backgroundWorker)
    {
        try
        {
            int RowCount = inputDataTable.Rows.Count;

            int orde = 7;
            int dataCount = inputDataTable.Rows.Count;
            double[] coef = new double[orde + 3];
            double[] distance = new double[dataCount];
            ...
            ...
            for(int i=0; i<newDataCount; i++)
            {
                ...
                backgroundWorker.ReportProgress(Convert.ToInt32(i * 80 / newDataCount));
            }
            return dT;
        }
        catch (Exception ex)
        {

            throw ex;
        }
    }

My question is, how the good way to cancel my backgroundworker? I just think to move this code:

if (worker.CancellationPending == true)
{
   e.Cancel = true;
}

to the class project, so I can stop the process immediately. But I couldn't do it. Can anyone help me?

================================

Update: the cancelation itself from other function:

    private void buttonCancel_Click(object sender, EventArgs e)
    {
        if (CalculateBackgroundWorker.WorkerSupportsCancellation == true)
        {
            CalculateBackgroundWorker.CancelAsync();
            LoaderForm.Close();
        }
    }

    private void CalculateButton_Click(object sender, EventArgs e)
    {
        try
        {
            ClearOutputDataTable();
            if (CalculateBackgroundWorker.IsBusy != true)
            {
                LoaderForm = new General.LoaderForm();
                LoaderForm.Canceled += new EventHandler<EventArgs>(buttonCancel_Click);
                LoaderForm.Show();
                LoaderForm.TopMost = true;
                CalculateBackgroundWorker.RunWorkerAsync();
            }
        }
        catch (Exception ex)
        {
              Messagebox.Show(ex.Message);
        }
    }

I update my question. So I have loading form that show the progress bar. It will appear during the calculation. This form has cancel button, that will execute to cancel the process.

this is code behind the loaderform:

public partial class LoaderForm : Form
{
    public LoaderForm()
    {
        InitializeComponent();
    }

    public string Message
    {
        set { PercentageLabel.Text = value; }
    }

    public int ProgressValue
    {
        set { LoadProgressBar.Value = value; }
    }

    public event EventHandler<EventArgs> Canceled;

    private void CancelButton_Click(object sender, EventArgs e)
    {
        EventHandler<EventArgs> ea = Canceled;
        if (ea != null)
            ea(this, e);
    }
}

Update 2: Even I call the cancellAsync, the proccess keep continue until finish. The code in BackgroundWorker_DoWork, only work in this condition (example):

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        for (int i = 1; i <= 10; i++)
        {
            if (worker.CancellationPending == true)
            {
                e.Cancel = true;
                break;
            }
            else
            {
                // Perform a time consuming operation and report progress.
                worker.ReportProgress(i * 10);
                System.Threading.Thread.Sleep(500);
            }
        }
    }

You should check BackgroundWorker.CancellationRequies in your Process method and exit if cancellation detected

for(int i=0; i<newDataCount; i++)
{
  if(backgroundWorker.CancellationPending)
  {
    return;
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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