有没有更好的方法来编写下面的代码来实现帖子主题中所述的内容?
我发现以下代码过于复杂且过于繁琐而使用额外的Subject<long>
,并且除非您在每个可观察对象中进行硬编码,否则不容易创建通用解决方案。
var subject = new Subject<long>();
var cts = new CancellationTokenSource();
var observable = Observable.Interval(TimeSpan.FromSeconds(2));
var disposable = observable.Do(l => {
{
Console.WriteLine($"Start {l}-{DateTime.Now}");
Thread.Sleep(2000);
Console.WriteLine($"Stop {l}-{DateTime.Now}");
subject.OnNext(l);
}
}).Subscribe();
cts.Token.Register(disposable.Dispose);
Thread.Sleep(5000);
subject.Subscribe();
cts.Cancel();
subject.FirstAsync().Wait();
Console.WriteLine("Finish");
答案 0 :(得分:3)
您最好使用Subject<Unit>
编写代码以表示完成。使用bool
数组有点乱,可能会让你在多线程代码中使用这种技术感到悲伤。
试试这个:
var observable = Observable.Interval(TimeSpan.FromSeconds(2));
Subject<Unit> finish = new Subject<Unit>();
observable
.TakeUntil(finish)
.Do(l =>
{
Console.WriteLine($"Start {l}-{DateTime.Now}");
Thread.Sleep(2000);
Console.WriteLine($"Stop {l}-{DateTime.Now}");
})
.Finally(() => Console.WriteLine("Finally"))
.Subscribe(
l => Console.WriteLine("OnNext"),
() => Console.WriteLine("Complete"));
Thread.Sleep(5000);
finish.OnNext(Unit.Default);
Console.ReadLine();
它产生:
Start 0-2017/08/15 13:37:03 Stop 0-2017/08/15 13:37:05 OnNext Start 1-2017/08/15 13:37:05 Stop 1-2017/08/15 13:37:07 OnNext Complete Finally
答案 1 :(得分:0)
实际上取消订阅导致没有进一步的信令。正确的做法是等待完成。订阅在完成后自动处理,因此无需进一步处理
var observable = Observable.Interval(TimeSpan.FromSeconds(2));
bool[] finish = {false};
observable.TakeWhile(l => !finish[0]).Do(l => {
Console.WriteLine($"Start {l}-{DateTime.Now}");
Thread.Sleep(2000);
Console.WriteLine($"Stop {l}-{DateTime.Now}");
}).Finally(() => Console.WriteLine("Finally")).Subscribe(l => {
Console.WriteLine("OnNext");
},() => Console.WriteLine("Complete") );
finish[0] = true;
Console.ReadKey(true);
以上产生相同的输出而没有额外的主题