Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to 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.
 
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 26-Mar-13 23:32pm
Edited 27-Mar-13 16:37pm
v11

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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/[^].
  Permalink  
Comments
dmunisubbu at 27-Mar-13 6:15am
   
Yes its already added abinav.
 
mWorker.WorkerSupportsCancellation = true;
dmunisubbu at 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)



Advertise | Privacy | Mobile
Web02 | 2.8.141220.1 | Last Updated 27 Mar 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100