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