Subscription on observable not reaching to oncompleted
我正在尝试为 wcf 调用创建一个可观察的package器,我创建如下。
方法是这样的,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | private IObservable<List<string>> Search(string searchTerm) { return Observable.Create<List<string>>(o => { var searchClient = new SearchServiceClient(); var s = Observable .FromEventPattern<SearchCompletedEventArgs>(searchClient,"SearchCompleted"); var subscription = s.Subscribe( r => { if (r.EventArgs.Error == null) o.OnNext(r.EventArgs.Result); else { o.OnError(r.EventArgs.Error); } }, e => { o.OnError(e); }, () => { o.OnCompleted(); }); searchClient.SearchAsync(searchTerm); return subscription; }); } |
和方法调用是,
1 2 3 4 5 6 7 8 9 10 11 12 13 | Search("reactive").Subscribe( r => { MessageBox.Show("Result"); }, e => { MessageBox.Show(e.ToString()); }, () => { MessageBox.Show("Completed"); }); |
但它永远不会到达已完成的块。你能建议我哪里出错了吗?
@26日编辑
感谢 Petar Vu??etin、Rarous 和 Lee Campbell。我已经测试了所有三个建议,并且都在工作。但我喜欢 Petar 对单行代码的处理方式。即使它似乎 Observable.FromAsyncPatterns 已被贬低。
@Rarous 是正确的。事件没有完成的概念,因此 FromEventPattern 永远不会完成(或错误)。我认为首选的方法是使用 Petar Vu??etin 指定的 Task.FromAsync.ToObservable,然后考虑 Rarous 指定的 FromAsyncPattern。如果您真的想这样做,您可以修改您的代码,使其看起来像这样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | private IObservable<List<string>> Search(string searchTerm) { return Observable.Create<List<string>>(o => { var searchClient = new SearchServiceClient(); var s = Observable .FromEventPattern<SearchCompletedEventArgs>(searchClient,"SearchCompleted"); var subscription = s.Subscribe( r => { if (r.EventArgs.Error == null) { o.OnNext(r.EventArgs.Result); o.OnCompleted(); } else { o.OnError(r.EventArgs.Error); } }); searchClient.SearchAsync(searchTerm); return subscription; }); } |
从事件创建的 Observable 永远不会运行到完成。正如 Petar 所提到的,您可以从异步模式创建 Observables。除了将
1 2 3 4 5 | IObservable<string[]> Search(string searchTerm) { var searchClient = new Service1Client(); return Observable.FromAsyncPatterns(searchClient.BeginGetData, searchClient.EndGetData)(searchTerm); } |
如果您可以为您的 WCF 客户端生成异步方法,您可以尝试这种方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | static void Main(string[] args) { var searcher = Search("test").Subscribe(Console.WriteLine); Console.WriteLine("Done"); Console.ReadLine(); } private static IObservable<string[]> Search(string searchTerm) { var searchClient = new Service1Client(); return Task<string[]>.Factory.FromAsync(searchClient.BeginGetData, searchClient.EndGetData, searchTerm, null).ToObservable(); } |