让我们说我希望公开一个可立即通知的观察者,如果现在有互联网连接,或者如果设备没有连接到互联网,则通知会在它成为时被推出可用的:
IObservable<DateTime> InternetBecameAvailableSignalledOncePerSubscriber { get; }
此外,每个订阅应该只有一个通知,而不要求订阅者.Take(1)或类似的东西。
即。依赖于Internet资源的客户端将使用此observable立即执行某些操作或在Internet可用时立即执行某项操作,但不会多次执行此操作 - 如果Internet不可用并且可用,则不再向该订户发送信号第二次..
如何使用Reactive Extensions(Rx)实现这一点?
答案 0 :(得分:1)
这应该可以通过Rx轻松解决。问题是你如何知道互联网是否可用?它是基于其他订阅者订阅的,是基于另一种方法(如Connect()
方法)还是某种被推送给你的事件(如WCF频道状态改变事件)?
根据这个答案,您似乎只需要封装Take(1)和Replay(1)。
public class IServiceClient
{
IObservable<DateTime> LastConnnected { get; }
}
public class ServiceClient : IServiceClient, IDisposable
{
private readonly IDisposable _connection;
private readonly IObservable<DateTime> _lastConnnected;
public ServiceClient()
{
//Question 1) where does the 'Connected' sequence come from i.e. what is it that tells you that you have internet connectivity?
//Question 2) When should the subscription be made to 'Connected'? Here I cheat and do it in the ctor, not great.
var connected = Connected.Replay(1)
.Where(isConnected=>isConnected)
.Take(1)
.Select(_=>DateTime.UtcNow);
_lastConnnected = connected;
_connection = connected.Connect();
}
public IObservable<DateTime> LastConnnected{ get {return _lastConnnected; } }
public void Dispose()
{
_connection.Dispose();
}
}
这确实会让您回答其他一些问题,例如:如果您有互联网连接以及资源管理计划是什么,会告诉您什么?
更新了代码
public interface IServiceClient
{
IObservable<DateTime> LastConnnected { get; }
}
public class ServiceClient : IServiceClient, IDisposable
{
private readonly IDisposable _connection;
private readonly IObservable<bool> _lastConnnected;
public ServiceClient(IObservable<ConnectionState> connectedStates)
{
var cachedStates = connectedStates.Select(state=>state.IsConnected).Replay(1);
_lastConnnected = cachedStates;
_connection = cachedStates.Connect();
}
public IObservable<DateTime> LastConnnected
{
get
{
return _lastConnnected.StartWith(IsConnected())
.Where(isConnected=>isConnected)
.Take(1)
.Select(_=>DateTime.UtcNow);
}
}
//....
public void Dispose()
{
_connection.Dispose();
}
}