mar*_*kin 1 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);
}
}
Run Code Online (Sandbox Code Playgroud)
正确的实施方法是什么?
编辑 为了回答 I3arnon 的问题,我使用 IDisposable 因为当我完成对象时,我希望它被垃圾收集。比如没有下面的f.Dispose()(取消任务,f好像不是Garbage Collected,或者cleanup任务取消了。有没有更好的实现方式?
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);
Run Code Online (Sandbox Code Playgroud)
这够好吗?您还可以通过接受委托在 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
可以删除 Task.Run 中的 async 和 await。它们只是为了清楚起见。
Task.Run(() => CleanupAsync());
归档时间: |
|
查看次数: |
7629 次 |
最近记录: |