C# 处理订阅时访问当前窗口
我有以下代码:C# 处理订阅时访问当前窗口,c#,system.reactive,C#,System.reactive,我有以下代码: var observable = ... subscribe to event here ... var windows = observable.Window(TimeSpan.FromSeconds(240)); aggregatedWindows = windows.SelectMany( window => window.Aggregate(new Context(), AggregateContext)); subscription = aggreg
var observable = ... subscribe to event here ...
var windows = observable.Window(TimeSpan.FromSeconds(240));
aggregatedWindows = windows.SelectMany(
window => window.Aggregate(new Context(), AggregateContext));
subscription = aggregatedWindows.Subscribe(OnWindow);
... later
subscription.Dispose();
想象一下,当我在处理窗口时,有人请求我的应用程序关闭。我将处理此订阅,这将停止正在处理的事件,但是我也将丢失最后一个信息窗口
我不确定处理这件事的最好方法是
我可以存储本地状态和最后一次看到的窗口,因为它是通过聚合函数传递的,但这似乎是错误的
任何帮助都将不胜感激 您可以对窗口进行操作,而不是保留聚合订阅,这是您主要希望在最后一个窗口到达时保持连接的窗口,并使用超时来断开连接,以防分区时间过长 这里使用了一个单独的类,因为使用Create会使其自动分离-这会在发出dispose调用后立即断开观察者的连接。因此,从根本上讲,Dispose的含义在这里发生了变化
public static IObservable<T> DeferDisconnection<T>(this IObservable<T> observable, TimeSpan timeout)
{
return new ClosingObservable<T>(observable, timeout);
}
public class ClosingObservable<T> : IObservable<T>
{
private readonly IConnectableObservable<T> Source;
private readonly IDisposable Subscription;
private readonly TimeSpan Timeout;
public ClosingObservable(IObservable<T> observable, TimeSpan timeout)
{
Timeout = timeout;
Source = observable.Publish();
Subscription = Source.Connect();
}
public IDisposable Subscribe(IObserver<T> observer)
{
Source.Subscribe(observer);
return Disposable.Create(() => Source.Select(_ => new Unit())
.Amb(Observable.Timer(Timeout).Select(_ => new Unit()))
.Subscribe(_ => Subscription.Dispose())
);
}
}
最后显示的部分窗口证实了这一点
class Program
{
public class Context
{
public int count;
}
static Context AggregateContext(Context c, long i)
{
c.count++;
return c;
}
static void OnWindow(Context c) { Console.WriteLine(c.count); }
static void Main(string[] args)
{
var canceled = new Subject<bool>();
var observable = Observable.Interval(TimeSpan.FromSeconds(.1)).TakeUntil(canceled);
var windows = observable.Window(TimeSpan.FromSeconds(3));
var aggregatedWindows = windows.SelectMany(
window => window.Aggregate(new Context(), AggregateContext));
var subscription = aggregatedWindows.Subscribe(OnWindow);
Thread.Sleep(TimeSpan.FromSeconds(10));
canceled.OnNext(true);
subscription.Dispose();
Console.WriteLine( @"Output should have been something like 30,30,30,30,10" );
Console.ReadLine();
}
}
我不明白这是如何解决问题的。看起来在处理之前,应用程序将等待一段时间,但如果窗口较大,则会导致应用程序等待很长时间才能关闭。这是正确的吗?@jonnii这就是为什么会有一个timeout参数-它会在下一个值到达时断开连接,或者如果它花费的时间太长,这就是timeout参数。
class Program
{
public class Context
{
public int count;
}
static Context AggregateContext(Context c, long i)
{
c.count++;
return c;
}
static void OnWindow(Context c) { Console.WriteLine(c.count); }
static void Main(string[] args)
{
var canceled = new Subject<bool>();
var observable = Observable.Interval(TimeSpan.FromSeconds(.1)).TakeUntil(canceled);
var windows = observable.Window(TimeSpan.FromSeconds(3));
var aggregatedWindows = windows.SelectMany(
window => window.Aggregate(new Context(), AggregateContext));
var subscription = aggregatedWindows.Subscribe(OnWindow);
Thread.Sleep(TimeSpan.FromSeconds(10));
canceled.OnNext(true);
subscription.Dispose();
Console.WriteLine( @"Output should have been something like 30,30,30,30,10" );
Console.ReadLine();
}
}