Click here to Skip to main content
15,886,518 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
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.

C#
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.
Posted
Updated 27-Mar-13 15:37pm
v11

1 solution

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/[^].
 
Share this answer
 
Comments
dmunisubbu 27-Mar-13 6:15am    
Yes its already added abinav.

mWorker.WorkerSupportsCancellation = true;
dmunisubbu 27-Mar-13 6:18am    
if we use the loop its cancelling.
In my case I am using sqldatareader. While running(it will take longtime to get the result) cmd.executereader(); if user press cancel
how can stop the process.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900