在WPF中取消BackgroundWorker [英] Cancel the BackgroundWorker in WPF
问题描述
在我的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 setWorkerSupportsCancellation
totrue
.
Try http://elegantcode.com/2009/07/03/wpf-multithreading-using-the-backgroundworker-and-reporting-the-progress-to-the-ui/[^].
这篇关于在WPF中取消BackgroundWorker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!