Reactive Extensions - 以同步方式刷新Subject / IObservable

时间:2017-06-30 15:26:57

标签: c# .net system.reactive reactive-programming

编辑:我编辑了几行代码,在IDE中运行时,它会在没有错误的情况下失败。

我是Reactive Extensions的新手,并且遇到了我正在努力解决的问题。我使用RX在一台机器上排队事件,然后经常将这些数据发送到服务器。我的问题似乎是当应用程序关闭时,任何类型的异步调用似乎只是取消而不是运行,因此最后一批事件永远不会被发送。

我有一个Subject,其中Event是我的数据类。我现在知道主题可能不是最好的类,但我们在这里。

我的代码看起来大致如下,为了清晰起见添加了一些注释:

IObservable<IList<Event>> eventsObserver = Instance.EventBuffer.ToList<Event>();
var eventsEnumerable = eventsObserver.ToEnumerable();
List<Event> events = new List<Event>();
try
{
    events = (List<Event>)eventsEnumerable.First();  // THIS LINE FAILS SILENTLY, EVEN IN DEBUGGER...
}

catch(Exception ex)
{
    System.Diagnostics.Debug.WriteLine("Error: " + ex.Message);
}

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(someURI);
    HttpResponseMessage response = client.PostAsync(somePage, new StringContent(SerializeToJSON(events))).Result;
    response.EnsureSuccessStatusCode();
}

如果我没有同步拨打网络服务器(使用&#39; .Result&#39;),则会失败。我已经尝试了很多方法将IObservable中的数据转换为我可以发送的内容,但是代码失败(通常是某种类型的错误转换),或者事件尚未放入数据结构中我想发送。我知道RX本质上是异步的,并且我要求以同步的方式处理它,我认为会有一个解决方案。提前谢谢!

1 个答案:

答案 0 :(得分:0)

假设您控制了Observable源,您可以像Enigmativity所指出的那样调用Observable.OnComplete()。否则,您可以尝试在缓冲之前保留每个接收到的值的副本:

Observable.Do(x => localCopy = x).Buffer(..)

您可以在关机时访问此本地副本。

在任何情况下,请注意.First()在最新的Rx版本中已标记为过时,可能是为了避免您遇到的问题。