加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 用于确保给定类型的单个未完成任务的模式

发布时间:2020-12-15 21:37:45 所属栏目:百科 来源:网络整理
导读:考虑以下: public class SomeService{ public Task StartAsync() { return Task.Factory .StartNew(() = DoStartup()); } public Task StopAsync() { return Task.Factory .StartNew(() = DoShutdown()); }} 上述问题是,如果多次调用StartAsync或StopAsync,
考虑以下:

public class SomeService
{
    public Task StartAsync()
    {
        return Task.Factory
            .StartNew(() => DoStartup());
    }

    public Task StopAsync()
    {
        return Task.Factory
            .StartNew(() => DoShutdown());
    }
}

上述问题是,如果多次调用StartAsync或StopAsync,则将创建多个任务来启动/停止服务.实际上,人们只希望一次启动一个启动/停止任务.为此,我通常做这样的事情:

public class SomeService
{
    private readonly object startSync = new object();
    private readonly object stopSync = new object();
    private Task startTask;
    private Task stopTask;

    public Task StartAsync()
    {
        var startTaskLocal = this.startTask;

        if (startTaskLocal != null)
        {
            return startTaskLocal;
        }

        lock (this.startSync)
        {
            if (this.startTask != null)
            {
                return this.startTask;
            }

            this.startTask = Task.Factory
                .StartNew(() => DoStartup())
                .Then(x =>
                    {
                        lock (this.stopSync)
                        {
                            this.stopTask = null);
                        }
                    });

            return this.startTask;
        }
    }

    public Task StopAsync()
    {
        // similar pattern to above
    }
}

现在虽然这有效,但它有点难看.在我试图将这种模式封装成小而可重复使用的东西之前,我已经走得太远了,我想知道是否有一种已经建立的方式这样做我不知道?

PS.我通过让StartAsync等待任何未完成的StopAsync调用来进一步扩展这个想法,反之亦然.这意味着任何时候都只能进行一次启动或停止操作.通过任务组合很容易做到这一点.如果我可以首先找出是否已经建立了完全实现上述目标的方法,那么我可以弄清楚它是否适合这种扩展行为.

解决方法

您可以使用 State Machine pattern.当代码进入AsyncStart时,将状态设置为Starting.我建议将对象的状态设置为Running的回调.

为Stopping,Stopped提供相同的功能.

因此,您的服务内部可能有一个ServiceState对象.在调用AsyncStart / AsyncStop之前,请检查当前状态.

更新
…另一种方式可能是存储和检查Cancellation Token.有关如何使用CancellationToken的无数样本.这只是我的头脑,而不是确认这是最好的方式.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读