Yog*_*esh 3 c# task-parallel-library system.reactive
我有一个要求,在10秒的初始延迟之后,我需要SomeMethod每10分钟执行一次,但是在完成之后应该启动10分钟计时器SomeMethod.这是一个粗略的例子:
Start Task 00:00:00
(10 second delay)
SomeMethod executed at 00:00:10 (takes 15 minutes)
(10 minute delay)
SomeMethod executed at 00:25:10
... and so on.
Run Code Online (Sandbox Code Playgroud)
我知道如何使用TPL来做到这一点.我可以使用Task.Delay启动任务并执行SomeMethod,然后在每次完成(ContinueWith TaskStatus.RanToCompletion)之后,我创建一个新任务并SomeMethod再次执行.
我的问题是,这有可能使用Observable.Timer吗?就像是...
Observable.Timer(TimeSpan.FromSeconds(10), TimeSpan.FromMinutes(10))
Run Code Online (Sandbox Code Playgroud)
这段代码的问题是,如果SomeMethod需要15分钟,我将SomeMethod运行两个不同的实例,这是我不想要的.我希望10分钟计时器在 SomeMethod完成后启动.这可能是使用Observable或应该留在TPL吗?
编辑:忘了提到我想SomeMethod在它自己的线程中运行.
您应该对使用进行更多调查Observable.Timer.它的工作方式几乎就像你想要直接开箱即用.
了解Rx的一个重要事项是,它可以保证您永远不会同时执行单个订阅.虽然Rx可能会启用各种多线程方案,但它始终会对订阅进行序列化.
因此,以此可观察订阅为例:
Observable
.Timer(TimeSpan.FromSeconds(10.0), TimeSpan.FromSeconds(2.0))
.Timestamp()
.Subscribe(x =>
{
Thread.Sleep(5000);
Console.WriteLine(x.ToString());
});
Run Code Online (Sandbox Code Playgroud)
我已经创建了一个observable,它将等待10秒钟开始发出值,然后尝试每2秒发出一个值.
然后我添加.Timestamp()了准确记录值的生成时间.
最后,我订阅了一个强制5秒线程睡眠的观察者.
这是前4个值输出:
0@2015-08-31 10:44:34 +00:00
1@2015-08-31 10:44:39 +00:00
2@2015-08-31 10:44:44 +00:00
3@2015-08-31 10:44:49 +00:00
Run Code Online (Sandbox Code Playgroud)
您会注意到值之间的差距是5秒.这非常接近你想要的.Rx看到两秒已经过去并立即执行下一个值.
但是还有另一个Rx运算符可以完全满足您的需求 - .Generate(...).这是一个非常强大的运算符,用于生成各种可观察的流.
你想像这样使用它:
Observable
.Generate(0, x => true, x => x + 1, x => x,
x => x == 0 ? TimeSpan.FromSeconds(10.0) : TimeSpan.FromSeconds(2.0))
.Timestamp()
.Subscribe(x =>
{
Thread.Sleep(5000);
Console.WriteLine(x.ToString());
});
Run Code Online (Sandbox Code Playgroud)
在这种情况下,它可以按照您想要的方式工作.这是前十个值:
0@2015-08-31 10:48:27 +00:00
1@2015-08-31 10:48:34 +00:00
2@2015-08-31 10:48:41 +00:00
3@2015-08-31 10:48:48 +00:00
4@2015-08-31 10:48:55 +00:00
5@2015-08-31 10:49:02 +00:00
6@2015-08-31 10:49:09 +00:00
7@2015-08-31 10:49:16 +00:00
8@2015-08-31 10:49:23 +00:00
9@2015-08-31 10:49:30 +00:00
Run Code Online (Sandbox Code Playgroud)
它每7秒发射一次.来自generate运算符的2和来自观察者的5.
显然,您可以投入所需的时间.
| 归档时间: |
|
| 查看次数: |
725 次 |
| 最近记录: |