关于BackgroundWorker的CancelAsync()

爱妃大大大 2013-08-28 05:37:07
大家好,
我最近正在研究BackgroundWorker的CancelAsync()事件。
我做的窗体中有两个按钮。当点击“导入”按钮时,实现将EXCEL文件导入到SQL数据库中。
现在想添加一个“取消”按钮,即终止该线程。

查了很多代码,发现跟我的代码思路不太一样。大家基本都是写在循环里面了,而我的代码里好像不太适合添加这种循环来实时判断CancellationPending,所以想请大家帮忙看看。

如果您能再多指点几句,那就更是感激不尽了。

多谢大家。

public partial class Form1 : Form
{
int Total = 0;

string[] FileNames;

private BackgroundWorker bkWorker = new BackgroundWorker();

public Form1()
{
InitializeComponent();

bkWorker.WorkerReportsProgress = true;
bkWorker.WorkerSupportsCancellation = true;
bkWorker.DoWork += new DoWorkEventHandler(DoWork);
bkWorker.ProgressChanged += new ProgressChangedEventHandler(ProgessChanged);
bkWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompleteWork);

}



private void 导入_Click(object sender, EventArgs e)
{


OpenFileDialog dlg = new OpenFileDialog();
dlg.Title = "请选择要导入的文件:";
dlg.Filter = "Excel文件(*.xls)|*.xls|所有文件|*.*";
dlg.Multiselect = true;




if (dlg.ShowDialog() == DialogResult.OK)
{

FileNames = dlg.FileNames;

foreach (string FileName in FileNames)
{
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" + FileName);

conn.Open();

DataTable table = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

for (int i = 0; i < table.Rows.Count; i++)
{
string TableName = table.Rows[i]["TABLE_NAME"].ToString();

if ((TableName.Substring(TableName.Length - 1, 1) == "$") || (TableName.Substring(0, 1) == "'"))
{
if ((TableName.Substring(TableName.Length - 2, 1) == "$"))
{
char[] TrimChar = { '\'' };
TableName = TableName.Trim(TrimChar);
TableName = TableName.Substring(0, TableName.Length - 1);
}
else
{
char[] TrimChar = { '\'', '$' };
TableName = TableName.Trim(TrimChar);
}

DataSet DS = new DataSet();

string strExcel = string.Format("select * from [{0}$]", TableName);

OleDbDataAdapter Adapter = new OleDbDataAdapter(strExcel, conn);

OleDbCommandBuilder Builder = new OleDbCommandBuilder(Adapter);

Adapter.Fill(DS, TableName);

Total = Total + DS.Tables[0].Rows.Count;


Builder.Dispose();
Adapter.Dispose();
DS.Dispose();
}
}

table.Dispose();
conn.Dispose();
}

this.progressBar1.Maximum = Total;

bkWorker.RunWorkerAsync();

}


}

public void DoWork(object sender, DoWorkEventArgs e)
{

string connString = "Server=GFKSAS3;UID=sa;PWD=f0reC0urt;Database=Northwind";

foreach (string FileName in FileNames)
{
OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" + FileName);

conn.Open();

DataTable table = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

for (int i = 0; i < table.Rows.Count; i++)
{
string TableName = table.Rows[i]["TABLE_NAME"].ToString();

if ((TableName.Substring(TableName.Length - 1, 1) == "$") || (TableName.Substring(0, 1) == "'"))
{
if ((TableName.Substring(TableName.Length - 2, 1) == "$"))
{
char[] TrimChar = { '\'' };
TableName = TableName.Trim(TrimChar);
TableName = TableName.Substring(0, TableName.Length - 1);
}
else
{
char[] TrimChar = { '\'', '$' };
TableName = TableName.Trim(TrimChar);
}


TransferData(FileName, TableName, connString);


}
}
table.Dispose();
conn.Dispose();
}

}

public void ProgessChanged(object sender, ProgressChangedEventArgs e)
{

this.progressBar1.Value = e.ProgressPercentage;

this.label1.Text = Convert.ToString(((e.ProgressPercentage) * 100 / progressBar1.Maximum)) + "%";

}

public void CompleteWork(object sender, RunWorkerCompletedEventArgs e)
{
this.progressBar1.Value = Total;
this.label1.Text = "完成!";
}


public void TransferData(string excelFile, string sheetName, string connectionString)
{

try
{
DataSet DS = new DataSet();

string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + excelFile + ";Extended Properties=Excel 8.0";

OleDbConnection conn = new OleDbConnection(strConn);

conn.Open();

string strExcel = string.Format("select * from [{0}$]", sheetName);

OleDbDataAdapter Adapter = new OleDbDataAdapter(strExcel, conn);

OleDbCommandBuilder Builder = new OleDbCommandBuilder(Adapter);

Adapter.Fill(DS, sheetName);

using (System.Data.SqlClient.SqlBulkCopy bcp = new System.Data.SqlClient.SqlBulkCopy(connectionString))
{

int Done = 0;
bcp.BatchSize = 1000;
bcp.NotifyAfter = 1000;
bcp.DestinationTableName = "test";
bcp.WriteToServer(DS.Tables[0]);

Done = Done + 1000;
bkWorker.ReportProgress(Done);

}


conn.Dispose();
Adapter.Dispose();
Builder.Dispose();
DS.Dispose();
}

catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
}

private void 取消_Click(object sender, EventArgs e)
{
bkWorker.CancelAsync();
}



}
...全文
487 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaozhunamen 2014-05-04
  • 打赏
  • 举报
回复
为什么要循环10次
爱妃大大大 2013-08-29
  • 打赏
  • 举报
回复
感谢二位。 您和网上查到的资料说的都一样。 能不能针对我提出的问题,提出一些建议?
devmiao 2013-08-28
  • 打赏
  • 举报
回复
在循环中加上一个bool值(NeedCancel),cancel触发改变bool值。 每次循环的时候都判断下,如果NeedCancel==true,就终止循环,退出。
卧_槽 2013-08-28
  • 打赏
  • 举报
回复
下面是博客园上的解释,你在发帖之前就不能看看msdn或者先google一下? 调用this.backgroundWorker1.CancelAsync()并不能结束后台线程, 要想提前结束这个线程,需要在你的DoWork事件事件处理函数中进行处理,示例代码如下: private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { for (int i = 0; i < 10; i++ ) { if ((BackgroundWorker)sender.CancellationPending) { e.Cancel = true; break; } //dosomething..... } } private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { //Cancelled } else { //Succeed } }

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧