当对象完成时取消任务

2023-12-31

我有一个启动任务的类,并希望确保该任务在对象被垃圾收集时停止。

我已经实现了 IDisposable 模式,以确保如果手动处理对象或在 using 块中使用对象,则任务会正确停止。However,我不能保证最终用户会调用 Dispose() 或在 using 块中使用该对象。我知道垃圾收集器最终会调用终结器 - 这是否意味着任务继续运行?

public class MyClass : IDisposable
{
    private readonly CancellationTokenSource feedCancellationTokenSource = 
          new CancellationTokenSource();

    private readonly Task feedTask;

    public MyClass()
    {
        feedTask = Task.Factory.StartNew(() =>
        {
            while (!feedCancellationTokenSource.IsCancellationRequested)
            {
                // do finite work
            }
        });
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            feedCancellationTokenSource.Cancel();
            feedTask.Wait();

            feedCancellationTokenSource.Dispose();
            feedTask.Dispose();
        }
    }

    ~MyClass()
    {
        Dispose(false);
    }
}

建议在这个问题 https://stackoverflow.com/questions/19196889/cancelling-tasks-in-the-dispose-method添加一个易失性布尔值,该布尔值是从终结器设置并从任务中观察到的。这是推荐的,还是有更好的方法来实现我的需要?

(我使用的是 .NET 4,因此使用 TaskFactory.StartNew 而不是 Task.Run)

EDIT:

为了给这个问题提供一些背景信息——上面的代码片段中实际上没有显示:我正在创建一个网络客户端类,它有一个通过定期向服务器发送数据包来保持活动状态的机制。我选择不在示例中添加所有这些细节,因为它与我的具体问题无关。然而,我真正想要的是用户能够将 KeepAlive 布尔属性设置为 true,这将启动一个任务,每 60 秒向服务器发送数据。如果用户将该属性设置为 false,则任务将停止。 IDisposable 让我完成了 90% 的工作,但是它依赖于用户正确地处理它(显式地或通过使用)。我不想向用户公开保持活动任务,以便他们显式取消,我只想要一个“简单”KeepAlive = true/false 来启动/停止任务,并且我希望任务在用户完成时停止该物体 - 即使他们没有正确处置它。我开始觉得这是不可能的!


我将画出一个答案。我不是 100% 相信这会起作用。最终确定是一个复杂的问题,我对此并不精通。

  1. 任务中不能有对象引用到任何应该最终确定的对象。
  2. 您不能从终结器中触摸不安全的其他对象。内置的 .NET 类通常不会记录此安全属性。你不能依赖它(通常)。
class CancellationFlag { public volatile bool IsSet; }

您现在可以在任务和任务之间共享此类的实例MyClass。该任务必须轮询标志并MyClass必须设置它。

为了确保任务永远不会意外引用外部对象,我将像这样构造代码:

Task.Factory.StartNew(TaskProc, state); //no lambda

static void TaskProc(object state) { //static
}

这样你就可以显式地将任何状态线程化state。这至少是一个例子CancellationFlag但在任何情况下都不会提及MyClass.

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

当对象完成时取消任务 的相关文章

  • 添加 Nullable int 时保持 null?

    我想添加可为空的int 并保留null当所有值都是null 我想要这个结果 1 2 3 1 null 1 null null null O null 0 问题是 如果我将一个值与 null 相加 结果为 null int i1 1 int
  • 将 new 与 decltype 一起使用

    T t T is an implementation detail t new T want to avoid naming T to allow for flexibility t new decltype t error cannot
  • 为什么 F# 的默认集合是排序的,而 C# 的不是?

    当从 C 世界迁移到 F 最惯用的可能 思维方式时 我发现了这个有趣的差异 在 C 的 OOP mutable 世界中 默认的集合集合似乎是HashSet https learn microsoft com en us dotnet api
  • 如何在另一个应用程序中挂钩 api 调用

    我正在尝试挂钩另一个应用程序的 ExtTextOut 和 DrawTextExt GDI 方法调用 我知道我需要使用 GetProcAddress 来查找 gdi32 dll 中那些方法的地址 并用我的函数的地址覆盖我想要挂钩的进程中的地址
  • C++ 长 switch 语句还是用地图查找?

    在我的 C 应用程序中 我有一些值充当代表其他值的代码 为了翻译代码 我一直在争论使用 switch 语句还是 stl 映射 开关看起来像这样 int code int value switch code case 1 value 10 b
  • linq 中使用字符串数组 c# 的 'orderby'

    假设我有一个这样的方法定义 public CustomerOrderData GetCustomerOrderData string CustomerIDs var query from a in db Customer join b in
  • 检测到堆栈崩溃

    我正在执行我的 a out 文件 执行后 程序运行一段时间 然后退出并显示消息 stack smashing detected a out terminated Backtrace lib tls i686 cmov libc so 6 f
  • 使用并行任务库时“foreach”失败

    以下代码创建正确数量的文件 但每个文件都包含第一个列表的内容 有人能发现我做错了什么吗 private IList
  • C# 编译器不会优化不必要的强制转换

    前几天 在写答案的时候这个问题 https stackoverflow com questions 2208315 why is any slower than contains在这里 关于溢出 我对 C 编译器感到有点惊讶 它没有按照我的
  • 根据对象变量搜索对象列表

    我有一个对象列表 这些对象具有三个变量 ID 名称和值 这个列表中可能有很多对象 我需要根据ID或Name找到一个对象 并更改值 例子 class objec public string Name public int UID public
  • 如何使用 NPOI 按地址(A1、A2)获取 Excel 单元格值

    我有一个 Excel 单元格地址 例如 A1 A2 如何使用 C 中的 NPOI 框架以编程方式访问此单元格 我找到的一些 Java POI 示例代码 CellReference cr new CellReference A1 row my
  • 从BackgroundWorker线程更新图像UI属性

    在我正在编写的 WPF 应用程序中 我有一个 TransformedBitmap 属性 该属性绑定到 UI 上的 Image 对象 每当我更改此属性时 图像就会更新 因此显示在屏幕上的图像也会更新 为了防止在检索下一张图像时 UI 冻结或变
  • 如何从 Rx Subscribe 回调异步函数?

    我想回调 Rx 订阅中的异步函数 例如 像那样 public class Consumer private readonly Service service new Service public ReplaySubject
  • 从浏览器访问本地文件?

    您好 我想从浏览器访问系统的本地文件 由于涉及大量安全检查 是否可以通过某种方式实现这一目标 或使用 ActiveX 或 Java Applet 的任何其他工作环境 请帮帮我 要通过浏览器访问本地文件 您可以使用签名的 Java Apple
  • ASP.NET MVC 路由:如何从 URL 中省略“索引”

    我有一个名为 StuffController 的控制器 具有无参数索引操作 我希望从表单中的 URL 调用此操作mysite com stuff 我的控制器定义为 public class StuffController BaseContr
  • 如何停止无限循环?

    我正在编写一个程序 该程序将计算三角形或正方形的面积 然后提示用户是否希望计算另一个 我的代码已经运行到可以计算任一形状的面积的程度 但随后不再继续执行代码的其余部分 例如 如果选择了正方形 则计算面积 然后返回到正方形边长的提示 我假设这
  • 使用 jQuery 从 ASP.Net JSON 服务获取数据

    我正在尝试调用 Google 地图地理编码 API 从纬度 经度对中获取格式化的地址 然后将其记录到控制台 我正在尝试获取为给定位置返回的第一个 formatted address 项目 我很简单无法从 JSON 中提取该项目 我不知道为什
  • C++ 中 void(*)() 和 void(&)() 之间的区别[重复]

    这个问题在这里已经有答案了 在此示例代码中 func1是类型void int double and funky是类型void int double include
  • DataContractSerializer 事件/委托字段问题

    在我的 WPF 应用程序中 我正在使用DataContractSerializer序列化对象 我发现它无法序列化具有事件或委托声明的类型 考虑以下失败的代码 Serializable public abstract class BaseCl
  • 如何使用placement new重新初始化该字段?

    我的课程包含字段 private OrderUpdate curOrderUpdate 我一遍又一遍地使用它 经常需要重新初始化 for int i 0 i lt entries size i auto entry entries i ne

随机推荐