编程语言
首页 > 编程语言> > c#-对象完成后取消任务

c#-对象完成后取消任务

作者:互联网

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

我已经实现了IDisposable模式,以确保如果手动放置对象或在using块内使用该对象,则Task可以正确停止.但是,我不能保证最终用户将调用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);
    }
}

this question中建议添加挥发性的bool,该挥发性的bool是在Finalizer中设置的,并从任务中观察到.是建议这样做,还是有更好的方法来实现我的需求?

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

编辑:

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

解决方法:

我会画一个答案.我不是100%确信这会起作用.终结是一个复杂的问题,我对此并不精通.

>从任务到要完成的任何对象都不能有对象引用.
>不能触摸终结器中其他不安全的对象.内置的.NET类通常不记录此安全属性. (通常)您不能依靠它.

class CancellationFlag { public volatile bool IsSet; }

现在,您可以在任务和MyClass之间共享此类的实例.任务必须轮询标志,而MyClass必须对其进行设置.

为了确保任务永远不会意外地引用外部对象,我将代码结构如下:

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

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

这样,您可以通过状态显式地线程化任何状态.这至少是CancellationFlag的一个实例,但在任何情况下都不会引用MyClass.

标签:finalizer,task-parallel-library,idisposable,task,c
来源: https://codeday.me/bug/20191118/2031219.html