当前位置: 移动技术网 > IT编程>开发语言>.net > aspnet core运行后台任务

aspnet core运行后台任务

2018年11月05日  | 移动技术网IT编程  | 我要评论

施密特逝世,小熊梦工厂下载,黑龙江省委书记陆昊

之前在公司的一个项目中需要用到定时程序,当时使用的是aspnet core提供的ihostedservice接口来实现后台定时程序,具体的示例可去官网查看。现在的dotnet core中默认封装了实现ihostedservice接口的基类backgroundservice,该类实现如下:

// copyright (c) .net foundation. all rights reserved.
// licensed under the apache license, version 2.0. see license.txt in the project root for license information.

using system;
using system.threading;
using system.threading.tasks;

namespace microsoft.extensions.hosting
{
    /// <summary>
    /// base class for implementing a long running <see cref="ihostedservice"/>.
    /// </summary>
    public abstract class backgroundservice : ihostedservice, idisposable
    {
        private task _executingtask;
        private readonly cancellationtokensource _stoppingcts = new cancellationtokensource();

        /// <summary>
        /// this method is called when the <see cref="ihostedservice"/> starts. the implementation should return a task that represents
        /// the lifetime of the long running operation(s) being performed.
        /// </summary>
        /// <param name="stoppingtoken">triggered when <see cref="ihostedservice.stopasync(cancellationtoken)"/> is called.</param>
        /// <returns>a <see cref="task"/> that represents the long running operations.</returns>
        protected abstract task executeasync(cancellationtoken stoppingtoken);

        /// <summary>
        /// triggered when the application host is ready to start the service.
        /// </summary>
        /// <param name="cancellationtoken">indicates that the start process has been aborted.</param>
        public virtual task startasync(cancellationtoken cancellationtoken)
        {
            // store the task we're executing
            _executingtask = executeasync(_stoppingcts.token);

            // if the task is completed then return it, this will bubble cancellation and failure to the caller
            if (_executingtask.iscompleted)
            {
                return _executingtask;
            }

            // otherwise it's running
            return task.completedtask;
        }

        /// <summary>
        /// triggered when the application host is performing a graceful shutdown.
        /// </summary>
        /// <param name="cancellationtoken">indicates that the shutdown process should no longer be graceful.</param>
        public virtual async task stopasync(cancellationtoken cancellationtoken)
        {
            // stop called without start
            if (_executingtask == null)
            {
                return;
            }

            try
            {
                // signal cancellation to the executing method
                _stoppingcts.cancel();
            }
            finally
            {
                // wait until the task completes or the stop token triggers
                await task.whenany(_executingtask, task.delay(timeout.infinite, cancellationtoken));
            }

        }

        public virtual void dispose()
        {
            _stoppingcts.cancel();
        }
    }
}
view code

根据backgroundservice源码,我们只要实现该类的抽象方法executeasync即可。
可以有两种实现方式来做定时程序,第一种就是实现一个timer:

using microsoft.extensions.hosting;
using microsoft.extensions.logging;
using system;
using system.io;
using system.threading;
using system.threading.tasks;

namespace demoone.models
{
    public class timedbackgroundservice : backgroundservice
    {
        private readonly ilogger _logger;
        private timer _timer;

        public timedbackgroundservice(ilogger<timedbackgroundservice> logger)
        {
            _logger = logger;
        }

        protected override async task executeasync(cancellationtoken stoppingtoken)
        {
            _timer = new timer(dowork, null, timespan.zero, timespan.fromseconds(5));
            _logger.loginformation("周六!");
            return task.completedtask;

            //console.writeline("myservicea is starting.");

            //stoppingtoken.register(() => file.create($"e:\\dotnetcore\\practice\\practice\\{datetime.now.millisecond}.txt"));

            //while (!stoppingtoken.iscancellationrequested)
            //{
            //    console.writeline("myservicea 开始执行");

            //    await task.delay(timespan.fromseconds(5), stoppingtoken);

            //    console.writeline("继续执行");
            //}

            //console.writeline("myservicea background task is stopping.");
        }

        private void dowork(object state)
        {
            _logger.loginformation($"hello world! - {datetime.now}");
        }

        public override void dispose()
        {
            base.dispose();
            _timer?.dispose();
        }
    }
}
view code

我们看看startasync的源码。上面的实现方式会直接返回一个已完成的task,这样就会直接运行startasync方法的if判断,那么如果我们不走if呢?那么就应该由startasync方法返回一个已完成的task.
第二个即是:

using microsoft.extensions.hosting;
using microsoft.extensions.logging;
using system;
using system.io;
using system.threading;
using system.threading.tasks;

namespace demoone.models
{
    public class timedbackgroundservice : backgroundservice
    {
        protected override async task executeasync(cancellationtoken stoppingtoken)
        {
            console.writeline("myservicea is starting.");

            stoppingtoken.register(() => file.create($"e:\\dotnetcore\\practice\\practice\\{datetime.now.millisecond}.txt"));

            while (!stoppingtoken.iscancellationrequested)
            {
                console.writeline("myservicea 开始执行");

                await task.delay(timespan.fromseconds(5), stoppingtoken);

                console.writeline("继续执行");
            }

            console.writeline("myservicea background task is stopping.");
        }

        public override void dispose()
        {
            base.dispose();
        }
    }
}
view code

最后我们将实现了backgroundservice的类注入到di即可:
services.addhostedservice<timedbackgroundservice>();

dotnet core的microsoft.extensions.hosting 组件中,充斥着类似ihostedservice接口中定义的方法:startasync、stopasync方法。我们注入的hostedservice服务会在webhost类中通过getrequiredservice获取到注入的定时服务。随后执行startasync方法开始执行。建议看看hosting组件源码,会有很多的收获。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网