关于 c#:Subscription on observable 未达到 oncompleted

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。除了将 Task 转换为 Observable 之外,您还可以使用工厂方法:

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();
        }