可观察对象的订阅未达到oncompleted
本文关键字:未达到 oncompleted 观察 对象 | 更新日期: 2023-09-27 18:10:43
我正在尝试为wcf调用创建一个可观察包装器,我创建如下:
方法是这样的,
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;
});
}
和方法调用是,
Search("reactive").Subscribe(
r =>
{
MessageBox.Show("Result");
},
e =>
{
MessageBox.Show(e.ToString());
},
() =>
{
MessageBox.Show("Completed");
});
但是它永远不会到达已完成的块。你能告诉我哪里不对吗?
@ 26日编辑
感谢Petar vu
@ rous是正确的。事件没有完成的概念,因此FromEventPattern永远不会完成(或出错)。我认为最好的方法是使用Petar vu
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;
});
}
如果您可以为WCF客户端生成Async方法,则可以尝试此方法。
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();
}
从事件创建的可观察对象永远不会运行到完成。正如Petar提到的,您可以从异步模式创建可观察对象。你可以使用工厂方法,而不是将Task
强制转换为Observable:
IObservable<string[]> Search(string searchTerm)
{
var searchClient = new Service1Client();
return Observable.FromAsyncPatterns(searchClient.BeginGetData, searchClient.EndGetData)(searchTerm);
}