在WPF中取消BackgroundWorker

问题描述:

在我的WPF Windows应用程序中,



当用户点击导出按钮时,我将大数据导出到后台工作程序中的.csv文件。



工作正常,但在这里我面临取消出口的问题。



我的问题是如何当用户点击取消按钮时取消后台进程。

这是详细的代码。

当它运行cmd.Excutereader();这里需要很长时间才能获得这个数据,我现在如何取消这个过程。



In My WPF Windows applications,

when user click on the export button, i am exporting large data to the .csv file in background worker.

Its working fine, but here i am facing the problem with cancelling the export.

My problem is how to cancel the Background process when user hits the cancel button.
Here is the detailed code.
when its running cmd.Excutereader();here it will take long time to get the data, at this time how do I cancel the process.

private void btnExport_Click(object sender, RoutedEventArgs e)
        {
            mWorker = new System.ComponentModel.BackgroundWorker();
            mWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
            mWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(worker_ProgressChanged);
            mWorker.WorkerReportsProgress = true;
            mWorker.WorkerSupportsCancellation = true;
            mWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
           
            
               dlg.FileName = "Document"; // Default file name
               dlg.DefaultExt = ".csv"; // Default file extension
               dlg.Filter = "CSV (Comma delimited) (*.csv)|*.csv"; // Filter files by extension
                Nullable<bool> result = dlg.ShowDialog();

                // Process save file dialog box results
                if (result == true)
                {
                    tabSchemeMngr.IsEnabled = false;
                    btnExport.IsEnabled = false;
                    if (dlg.FileName != "")
                    {
                        filename = dlg.FileName;

                        StartWorker();
                    }
                }
        }
	void StartWorker()
        {
            if (!mWorker.IsBusy)
            {
                mWorker.RunWorkerAsync();
            }
            // Unblock the worker 
            _busy.Set();
            
        }
        void CancelWorker()
        {
            if (mWorker.IsBusy)
            {
                mWorker.CancelAsync();
                // Unblock worker so it can see that
                _busy.Set();
            }
        }
        void PauseWorker()
        {
            // Block the worker
            _busy.Reset();
        }
private void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            System.IO.StreamWriter sw = new System.IO.StreamWriter(filename, false);

            SqlConnection sqlConnection = new SqlConnection(ConnectionStr);
            SqlCommand cmd = new SqlCommand("PROC_IED_ExporttoText", sqlConnection);
            cmd.CommandTimeout = 0;
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@p_DataBaseName", SelectedDatabase);
            cmd.Parameters.AddWithValue("@p_DistributionScheme", SelectedSchemeName);
            cmd.Parameters.AddWithValue("@p_Peril", SelectedPeril);
            cmd.Parameters.AddWithValue("@p_Occupancy", SelectedOccupancy);
            cmd.Parameters.AddWithValue("@p_Country", SelectedCountry);
            cmd.Parameters.AddWithValue("@p_State", selectedState);
            cmd.Parameters.AddWithValue("@p_County", SelectedCounty);
            cmd.Parameters.AddWithValue("@p_Zip", SelectedZip);
            cmd.Parameters.AddWithValue("@p_YearBuilt", SelectedYearBuilt);
            cmd.Parameters.AddWithValue("@p_ConstructionClass", SelectedConstrunctionClass);
            cmd.Parameters.AddWithValue("@p_BuildingHeight", SelectedBuildingHeight);
            cmd.Parameters.AddWithValue("@p_Year", SelectedYear);
            cmd.Parameters.AddWithValue("@p_Measures", SelectedMeasures);
            cmd.Parameters.AddWithValue("@p_AggregateLevel", SelectedAggregate);
            //cmd.Parameters.AddWithValue("@p_GeoFilterType", "");
            cmd.Parameters.AddWithValue("@p_TlLatitude", SelectedCoordinateTopX);
            cmd.Parameters.AddWithValue("@p_TlLongitude", SelectedCoordinateTopY);
            cmd.Parameters.AddWithValue("@p_BrLatitude", SelectedCoordinateBottomX);
            cmd.Parameters.AddWithValue("@p_BrLongitude", SelectedCoordinateBottomY);

            DataTable dsYear = new DataTable();
          
            try
            {
                sqlConnection.Open();
               
                if (filename != "")
                {

                    //For getting the Table Headers
                    SqlDataReader export = cmd.ExecuteReader();
                    _busy.WaitOne();
                    // Check if the user wants to abort
                    if (mWorker.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }
                    DataTable Tablecolumns = new DataTable();
                    for (int i = 0; i < export.FieldCount; i++)
                    {
                        Tablecolumns.Columns.Add(export.GetName(i));
                    }
                    sw.WriteLine(string.Join(",", Tablecolumns.Columns.Cast<DataColumn>().Select(csvfile => csvfile.ColumnName)));

                    while (export.Read())
                    {
                        strRow = "";
                        for (int i = 0; i < export.FieldCount; i++)
                        {
                            strRow += export.GetValue(i).ToString();
                            if (i < export.FieldCount - 1)
                            {
                                strRow += this.separator;
                            }
                        }
                        sw.WriteLine(strRow);
                    }
                    sw.Close();
                    }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (sqlConnection != null)
                    sqlConnection.Dispose();
            }
        }
private void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
        {
           
        }
        private string separator
        {
            get
            {
                return ",";
            }
        }
 private void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
           // Check the result
            if (e.Cancelled)
            {
                // show the message box that the task has been canceled
                Xceed.Wpf.Toolkit.MessageBox.Show("Has been cancelled");
            }
            
        }
private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            PauseWorker();
            if (MessageBox.Show("Are you sure you want to cancel the Export?", "Message Alert", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
            {
                CancelWorker();
            }
            else
            {
                StartWorker();
            }
        }



如果您有任何想法,请告诉我。


Kindly tell me if you have any ideas to do this.

你不能直接这样做。首先需要将 WorkerSupportsCancellation 设置为 true

尝试 http://elegantcode.com/2009/07 / 03 / wpf-multithreading-using-the backgroundworker-and-reporting-the-progress-to-the-ui / [ ^ ]。
You can''t directly do this. You first need to set WorkerSupportsCancellation to true.
Try http://elegantcode.com/2009/07/03/wpf-multithreading-using-the-backgroundworker-and-reporting-the-progress-to-the-ui/[^].