考虑以下:
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的无数样本.这只是我的头脑,而不是确认这是最好的方式.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。