gpt4 book ai didi

c# - 如何中断现有的 IObservable 序列?

转载 作者:太空宇宙 更新时间:2023-11-03 15:11:00 24 4
gpt4 key购买 nike

我有

我有一个由触摸事件组成的可观察序列:

 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 序列?

最佳答案

这是一个 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

关于c# - 如何中断现有的 IObservable 序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41144774/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com