定期后台任务 [英] Recurring Background Task

查看:126
本文介绍了定期后台任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始尝试使用,而不是线程任务,我试图实现与每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());

这篇关于定期后台任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆