我有一个由触摸事件制作的可观察序列:
var touchEvents = Observable.Merge(
Observable.FromEventPattern<RoutedEventArgs>(touchRect, nameof(touchRect.PointerEntered)),
Observable.FromEventPattern<RoutedEventArgs>(touchRect, nameof(touchRect.PointerExited)),
Observable.FromEventPattern<RoutedEventArgs>(touchRect, nameof(touchRect.PointerReleased)));
我观察直到满足特定条件:
async void Start()
{
_scanSlapObservable = touchEvents.Throttle(TimeSpan.FromSeconds(1))
.Where(e => countOfPointers == expectedFingers.Length)
.Select(e => new Response())
.FirstOrDefaultAsync();
Response response = await _scanSlapObservable;
if (response != null)
{
//do something
}
}
当我两次调用Start()
时,我想中断现有的_scanSlapObservable
,因此它返回null或抛出异常。
如何中断现有的IObservable序列?
答案 0 :(得分:0)
这是Linqpad友好的解决方案。丑陋,但它确实有效:
async Task Main()
{
var sc = new ScanClass();
sc.Start();
sc.touchEvents.OnNext(Unit.Default);
sc.touchEvents.OnNext(Unit.Default);
sc.Start();
sc.touchEvents.OnNext(Unit.Default);
sc.touchEvents.OnNext(Unit.Default);
await Task.Delay(TimeSpan.FromSeconds(1));
}
// Define other methods and classes here
class ScanClass
{
IObservable<Response> _scanSlapObservable;
public Subject<Unit> _interrupter = new Subject<Unit>();
public Subject<Unit> touchEvents = new Subject<Unit>();
public async Task Start()
{
_interrupter.OnNext(Unit.Default);
_scanSlapObservable = touchEvents
.Throttle(TimeSpan.FromSeconds(1))
// .Where(e => countOfPointers == expectedFingers.Length)
.Select(e => new Response())
.TakeUntil(_interrupter)
.FirstOrDefaultAsync();
Response response = await _scanSlapObservable;
if (response != null)
{
//do something
Console.WriteLine("Do Something");
}
else
{
Console.WriteLine("Null Response");
}
}
}
class Response { }
我认为最好的方法是Switch
风格,但这不适用于Task
。我认为丑陋的很大一部分是将Task
API与Rx混合在一起。这是Rx专用解决方案的样子:
class ScanClass
{
public Subject<Unit> _starter = new Subject<Unit>();
public Subject<Unit> touchEvents = new Subject<Unit>();
public ScanClass()
{
_starter.Select(_ => touchEvents
.Throttle(TimeSpan.FromSeconds(1))
// .Where(e => countOfPointers == expectedFingers.Length)
.Select(e => new Response())
)
.Switch()
.Subscribe(r => Console.WriteLine("Do Something."));
}
public async Task Start()
{
_starter.OnNext(Unit.Default);
}
}
...理想情况下,您会使用某种Start()
替换_starter
和Observable.FromEvent
。