经常性背景任务

我刚刚开始尝试使用“任务”而不是线程,并尝试使用后台“清理”任务实现一个对象,该任务每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); 

这够好吗? 您还可以通过接受委托在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中的async和await。 它们只是为了清晰起见。 Task.Run(() => CleanupAsync());