BackgroundWorker - Cancellation Pending 在 RunWorkerCompleted 中更改为 false。为什么?

2024-04-01

取消BackGroundWorker后,在DoWork中,CancellationPending为true,但是当他来到RunWorkerCompleted时,CancellationPending为false。我不知道我做错了什么?

static BackgroundWorker b1;

static void Main(string[] args)
{
    b1=new BackgroundWorker();
    b1.DoWork += new DoWorkEventHandler(work1);
    b1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(completed);
    b1.WorkerSupportsCancellation = true;
    b1.RunWorkerAsync("Hellow");
    Console.ReadLine();
}

private static void completed(object sender, RunWorkerCompletedEventArgs e)
{
    if (((BackgroundWorker)sender).CancellationPending)
        Console.WriteLine("Canceled!");
    else
        Console.WriteLine("Result:" + e.Result);//it goes here every time
}

private static void work1(object sender, DoWorkEventArgs e)
{
    ((BackgroundWorker)sender).CancelAsync();
    if (((BackgroundWorker)sender).CancellationPending)
    {
        e.Cancel = true;
    }
}

顺便说一句,如何将 DoWork 中发生的错误添加到 RunWorkerCompletedEventArgs.Error 中以将其显示给用户?


是的,BackgroundWorker 类在引发 RunWorkerCompleted 事件之前将 CancellationPending 属性设置为 false。工人是否真的被取消了。

这是有意为之的,它可以防止您陷入使用线程时始终存在的令人讨厌的陷阱。由于一种称为“线程竞争”的错误,使用线程的代码通常会随机且不可预测地出现错误行为。这是一种非常常见的错误,并且非常难以调试。

如果 BGW 没有这样做,您的预期方法中很容易出错的是,当您看到 CancellationPending 设置为 true 时,您会认为工作线程已被取消。但这是一种错觉,你无法区分它被取消和正常完成之间的区别。极端情况是您在工作线程完成前一微秒调用 CancelAsync() 。工作线程甚至没有机会看到 CancellationPending 标志设置为 true,它正忙着完成 DoWork 事件处理程序方法的最后几位。这是一场线程竞赛,工作人员在您的调用之前竞赛并正常完成。

避免此错误的正确握手方法是,当工作线程看到 CancellationPending 属性设置为 true 时,将 e.Cancel 设置为 true。当然还要停止它正在做的事情。现在可靠了,RunWorkerCompleted 事件处理程序中的 e.Cancelled 属性是 e.Cancel 的副本。因此,您的代码现在可以可靠地告诉您工作人员是否看到了取消请求。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

BackgroundWorker - Cancellation Pending 在 RunWorkerCompleted 中更改为 false。为什么? 的相关文章

  • C++ 维护子类对象的混合集合

    如果我在这里错过了一个相当基本的概念 我很抱歉 但我正在尝试弄清楚如何维护多个类类型的集合 所有类类型都派生自同一个父类 并且在检索它们时仍然可以访问它们的特定于子类的方法从集合中 作为上下文 我有一个基类 BaseClass 和许多类 例
  • 静态只读字符串数组

    我在我的 Web 应用程序中使用静态只读字符串数组 基本上数组有错误代码 我将所有类似的错误代码保存在一个数组中并检查该数组 而不是检查不同常量字符串中的每个错误代码 like public static readonly string m
  • 使用 lambda 表达式注册类型

    我想知道如何在 UnityContainer 中实现这样的功能 container RegisterType
  • 适合初学者的良好调试器教程[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有谁知道一个好的初学者教程 在 C 中使用调试器 我感觉自己好像错过了很多 我知道怎么做 单步执行代码并查看局部变量 虽然这常常给我带来问
  • 如何捕获未发送到 stdout 的命令行文本?

    我在项目中使用 LAME 命令行 mp3 编码器 我希望能够看到某人正在使用什么版本 如果我只执行 LAME exe 而不带参数 我会得到 例如 C LAME gt LAME exe LAME 32 bits version 3 98 2
  • Visual Studio 在构建后显示假错误

    我使用的是 Visual Studio 2017 构建后 sln在调试模式下 我收到错误 但是 当我通过双击错误列表选项卡中的错误来访问错误时 错误会从页面中消失 并且错误数量也会减少 我不太确定这种行为以及为什么会发生这种情况 有超过 2
  • 从客户端访问 DomainService 中的自定义对象

    我正在使用域服务从 Silverlight 客户端的数据库中获取数据 在DomainService1 cs中 我添加了以下内容 EnableClientAccess public class Product public int produ
  • 使用 GCP 的数据存储区时如何区分代码是在模拟器中运行还是在 GKE 中运行

    按照中给出的说明进行操作后 我不确定是否遗漏了任何内容https cloud google com datastore docs tools datastore emulator https cloud google com datasto
  • 在Linux中,找不到框架“.NETFramework,Version=v4.5”的参考程序集

    我已经设置了 Visual studio 来在我的 Ubuntu 机器上编译 C 代码 我将工作区 我的代码加载到 VS 我可以看到以下错误 The reference assemblies for framework NETFramewo
  • 告诉 Nancy 将枚举序列化为字符串

    Nancy 默认情况下在生成 JSON 响应时将枚举序列化为整数 我需要将枚举序列化为字符串 有一种方法可以通过创建来自定义 Nancy 的 JSON 序列化JavaScript 原始转换器 https github com NancyFx
  • 将 Long 转换为 DateTime 从 C# 日期到 Java 日期

    我一直尝试用Java读取二进制文件 而二进制文件是用C 编写的 其中一些数据包含日期时间数据 当 DateTime 数据写入文件 以二进制形式 时 它使用DateTime ToBinary on C 为了读取 DateTime 数据 它将首
  • C# 存档中的文件列表

    我正在创建一个 FileFinder 类 您可以在其中进行如下搜索 var fileFinder new FileFinder new string C MyFolder1 C MyFolder2 new string
  • 使用valgrind进行GDB远程调试

    如果我使用远程调试gdb我连接到gdbserver using target remote host 2345 如果我使用 valgrind 和 gdb 调试内存错误 以中断无效内存访问 我会使用 target remote vgdb 启动
  • 为什么从字典中获取时会得到 Action<> 的克隆?

    我有以下字典 private Dictionary
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 等待 IAsyncResult 函数直至完成

    我需要创建等待 IAsyncResult 方法完成的机制 我怎样才能做到这一点 IAsyncResult result contactGroupServices BeginDeleteContact contactToRemove Uri
  • 检测到严重错误 c0000374 - C++ dll 将已分配内存的指针返回到 C#

    我有一个 c dll 它为我的主 c 应用程序提供一些功能 在这里 我尝试读取一个文件 将其加载到内存 然后返回一些信息 例如加载数据的指针和内存块的计数到 c Dll 成功将文件读取到内存 但在返回主应用程序时 程序由于堆损坏而崩溃 检测
  • 打印大型 WPF 用户控件

    我有一个巨大的数据 我想使用 WPF 打印 我发现WPF提供了一个PrintDialog PrintVisual用于打印派生的任何 WPF 控件的方法Visual class PrintVisual只会打印一页 因此我需要缩放控件以适合页面
  • 这个可变参数模板示例有什么问题?

    基类是 include
  • Objective-C / C 给出枚举默认值

    我在某处读到过关于给枚举默认值的内容 如下所示 typedef enum MarketNavigationTypeNone 0 MarketNavigationTypeHeirachy 1 MarketNavigationTypeMarke

随机推荐