我刚开始尝试使用,而不是线程任务,我试图实现与每5分钟,只要对象是使用,但它不应该阻止垃圾运行的背景清理任务的对象集合。
粗制滥造的东西线沿线的(这显然是行不通的......)
公共类Foo:IDisposable接口{ 私人CancellationTokenSource _tokenSource =新CancellationTokenSource(); 公共美孚() { 清理(); } 公共无效的Dispose() { _tokenSource.Cancel(); } 公共无效清除() { Task.Delay(TimeSpan.FromSeconds(5),_tokenSource.Token).ContinueWith(叔= GT; { //做工作 如果(!_tokenSource.IsCancellationRequested) { 清理(); } },TaskContinuationOptions.NotOnCanceled); }}什么是实施正确的方法是什么?
修改在回答I3arnon的问题,我使用了IDisposable,因为当我与对象完成,我希望它是垃圾回收。例如,没有f.Dispose()以下(其中取消了任务,F没有出现被垃圾收集或清理任务取消。是否有实现更好的办法?
变种F =新的Foo();变种R =新的WeakReference(F);Thread.sleep代码(TimeSpan.FromSeconds(15));f.Dispose();F = NULL;System.GC.Collect();Thread.sleep代码(TimeSpan.FromSeconds(5));Console.WriteLine(r.IsAlive);解决方案
是不够好?您也可以让这个类通过接受委托的,而内运行通用的,可重复使用。我真的不知道为什么你需要它是一个IDisposable接口,虽然...
公共类Foo:IDisposable接口{ 私人CancellationTokenSource _tokenSource =新CancellationTokenSource(); 公共美孚() { Task.Run(异步()=>等待CleanupAsync()); } 公共无效的Dispose() { _tokenSource.Cancel(); } 公共异步任务CleanupAsync() { 而(!_tokenSource.Token.IsCancellationRequested) { //你需要的任何清理。 等待Task.Delay(TimeSpan.FormSeconds(5),_ tokenSource.Token); } }}的 Task.Run内的异步和等待可以被删除。他们只是在那里清晰度。 Task.Run(()=> CleanupAsync());
I am just starting to try to use "Tasks" instead of Threads and am trying to implement an object with a background "cleanup" task that runs every 5 minutes as long as the object is in use but which should not block garbage collection.
Something crudely along the lines of (which obviously doesn't work...)
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); } }What is the correct way to implement?
EDIT In response to I3arnon's question, I am using IDisposable because when I am done with the object, I want it to be garbage collected. For example, without the f.Dispose() below (which cancels the task, f does not appear to be Garbage Collected, or the cleanup task canceled. Is there a better way to implement?
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);解决方案
Is that good enough? You can also make this class generic and reusable by accepting a delegate to run inside the while. I'm not really sure why you need it to be an IDisposable though...
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.FormSeconds(5),_tokenSource.Token); } } }The async and await inside the Task.Run can be removed. They are just there for clarity. Task.Run(() => CleanupAsync());
更多推荐
定期后台任务
发布评论