c# - 在 winforms 中取消工作线程

标签 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;
}

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

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

我还需要做些什么来取消此线程的返回吗?

最佳答案

您的方法 bg_LoadAllWork 应定义为:

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

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

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

关于c# - 在 winforms 中取消工作线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1013820/

相关文章:

c# - 为什么 IQueryable 缺少 IQueryable<T> 拥有的所有扩展方法?

c# - C# 方法是否允许可空列表作为参数?

vb.net - 在不卡住 UI 的情况下向 ListView 添加 150,000 条记录

c# - 在 Winforms 自定义 UserControl 上启用设计界面

multithreading - 什么是竞争条件?

java - 如何从 map 中获取数据?

c# - 可以将私有(private)方法放在我的 Controller 中,还是应该使用 asp.net mvc 将它们分离到某种类型的帮助程序类中?

c# - Ubuntu 16.10 上的 OmniSharp-VIM、OmniSharp-Roslyn 和 dotnet 核心 - 语法检查无法识别 C# 6 并且需要解决方案文件

c# - Excel 之上的 Windows 窗体

java - 线程结束后再次执行