C# 经常性后台任务
我刚刚开始尝试使用任务而不是线程,并尝试实现一个具有后台清理任务的对象,该任务每5分钟运行一次,只要该对象正在使用,但不应阻止垃圾收集 一些粗制滥造的东西显然是行不通的C# 经常性后台任务,c#,task-parallel-library,async-await,c#-5.0,C#,Task Parallel Library,Async Await,C# 5.0,我刚刚开始尝试使用任务而不是线程,并尝试实现一个具有后台清理任务的对象,该任务每5分钟运行一次,只要该对象正在使用,但不应阻止垃圾收集 一些粗制滥造的东西显然是行不通的 public class Foo : IDisposable { private CancellationTokenSource _tokenSource = new CancellationTokenSource(); public Foo() { Cleanup();
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);
}
}
正确的实施方法是什么
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);
在回答I3arnon的问题时,我使用IDisposable,因为当我处理完对象时,我希望它被垃圾收集。例如,如果下面没有取消任务的f.Dispose,则f不会被垃圾回收,或者清理任务被取消。有没有更好的实施方法
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和Wait。它们只是为了清晰起见。
Task.Run=>cleanupsync 这够好吗?您还可以通过接受在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和Wait。它们只是为了清晰起见。
Task.Run=>cleanupsync 实现dispose允许您使用。这是一个很好的简洁易懂的简写,我已经完成了。我知道,但我怀疑他是否会在同一个使用范围内使用每5秒做一次事情的类。可以说,这取决于他为什么每5秒清理一次—这本身就是一种奇怪的做法。实现dispose允许您使用。这是一个很好的简洁易懂的简写,我已经完成了。我知道,但我怀疑他是否会在同一个使用范围内使用每5秒做一次事情的类。可以说,这取决于他为什么每5秒钟清理一次——这本身就是一种奇怪的做法。试试看,在.NET中没有确定性对象终结。试试看,在.NET中没有确定性对象终结。