经常性背景任务

时间:2013-12-29 21:40:15

标签: c# task-parallel-library async-await c#-5.0

我刚刚开始尝试使用“任务”而不是线程,并尝试使用后台“清理”任务实现一个对象,该任务每5分钟运行一次,只要该对象正在使用但不应该阻止垃圾集合。

粗略地说明了某些事情(显然不起作用......)

public class Foo : IDisposable
{
    private CancellationTokenSource _tokenSource = new CancellationTokenSource();

    public Foo()
    {
        Cleanup();      
    }

    public void Dispose()
    {
        _tokenSource.Cancel();
    }

    public void Cleanup()
    {
        Task.Delay(TimeSpan.FromSeconds(5), _tokenSource.Token).ContinueWith(t => 
        {
            //Do Work
            if (!_tokenSource.IsCancellationRequested)
            {
                Cleanup();
            }
        }, TaskContinuationOptions.NotOnCanceled);
    }
}

实施的正确方法是什么?

编辑为了回应I3arnon的问题,我正在使用IDisposable,因为当我完成对象时,我希望它被垃圾收集。例如,如果没有下面的f.Dispose()(取消任务,f似乎不是Garbage Collected,或者取消了清理任务。有没有更好的实现方法?

var f = new Foo();
var r = new WeakReference(f);
Thread.Sleep(TimeSpan.FromSeconds(15));
f.Dispose();
f = null;
System.GC.Collect();
Thread.Sleep(TimeSpan.FromSeconds(5));
Console.WriteLine(r.IsAlive);

1 个答案:

答案 0 :(得分:4)

这够好吗?您还可以通过接受委托在while内部运行来使此类具有通用性和可重用性。我不确定为什么你需要它才能成为IDisposable ......

public class Foo : IDisposable
{
    private CancellationTokenSource _tokenSource = new CancellationTokenSource();

    public Foo()
    {
        Task.Run(async () => await CleanupAsync());
    }

    public void Dispose()
    {
        _tokenSource.Cancel();
    }

    public async Task CleanupAsync()
    {
        while (!_tokenSource.Token.IsCancellationRequested)
        {
           // Do whatever cleanup you need to.

           await Task.Delay(TimeSpan.FromSeconds(5),_tokenSource.Token);
        }
    }
}

可以删除Task.Run中的异步和等待。它们只是为了清晰起见。 Task.Run(() => CleanupAsync());