取消winforms中的工作线程

时间:2009-06-18 16:44:04

标签: c# winforms multithreading backgroundworker

我有两个列表框,一个是主人,另一个是孩子。当索引在主服务器上更改时,子列表框将适当地填充与主服务器相关的记录。当一个主人需要很长时间才能获得所有记录并且在完成记录之前,用户点击一个花费更少时间填充的不同主人时,我的问题就出现了。最后,即使用户不在那个主人身上,那么花费更长时间的主人也会填充子列表框。

我一直在使用BackgroundWorker线程进行填充。

bw_LoadAll.DoWork += new DoWorkEventHandler(bg_LoadAllWork);
bw_LoadAll.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_LoadAllWorkCompleted);
bw_LoadAll.WorkerSupportsCancellation = true;

我订阅了master的SelectedIndexChanged事件,并将取消的等于true设置为:

bw_LoadAll.CancelAsync();

以下是DoWork方法中的代码:

List<object> s = Repository.Instance().LoadAll();
if (!bw_LoadAll.CancellationPending) {
    e.Result = s;
} else {
    e.Cancel = true;
}

但由于某种原因,完成的工作人员的代码不断被调用。这是工作人员完成的代码:

if (!e.Cancelled) {
    ddl.DataSource = e.Result;
    ddl.DisplayMember = "QuickName";
    ddl.ValueMember = "ID";
}

我还有别的办法可以取消这个帖子吗?

3 个答案:

答案 0 :(得分:5)

您的方法bg_LoadAllWork应定义为:

void bg_LoadAllWork(object sender, DoWorkEventArgs e)
{
    // Do your work here...
} 

在bg_LoadAllWork内部,您需要检查e.CancellationPending,如果是,请设置e.Cancel = true;

这最后一部分很重要 - 如果你从未设置e.Cancel,那么你的“e.Cancelled”将永远不会成立。对CancelAsync的调用实际上并没有取消任何东西 - 它更像是“请求后台工作取消自己” - 你必须放置逻辑以导致取消。

答案 1 :(得分:0)

从do_work函数中的CodeProject开始,您需要在工作线程上检查CancellationPending,然后将DoWorkEventArgs.Cancel变量设置为true。

答案 2 :(得分:0)

我使用了BackgroundWorker已经有一段时间了,但如果我有内存服务,当你致电bw_LoadAll.CancelAsync时,除非LoadAllWork检查LoadAllWork,否则你的bw_LoadAll.CancelationPending方法没有实际中止

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.cancelasync.aspx确认:“CancelAsync提交终止待处理后台操作的请求,并将CancellationPending属性设置为true。

当您调用CancelAsync时,您的worker方法有机会停止执行并退出。工作人员代码应定期检查CancellationPending属性,看它是否已设置为true。“

因此,在您的SelectedIndexChanged事件处理程序中,当您调用bw_LoadAll.CancelAsync()时,它将bw_LoadAll.CancelationPending设置为true,但它实际上并未中止LoadAllWork方法。慢装载机仍将完成。