使用 Rx 对 Bing 地图中的地址进行地理编码
我正在学习如何使用我正在开发的 Silverlight 4 应用程序的 Rx 扩展。我创建了一个示例应用程序来确定该过程,但我无法让它返回任何内容。 这是主要代码:
private IObservable<Location> GetGPSCoordinates(string Address1)
{
var gsc = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService") as IGeocodeService;
Location returnLocation = new Location();
GeocodeResponse gcResp = new GeocodeResponse();
GeocodeRequest gcr = new GeocodeRequest();
gcr.Credentials = new Credentials();
gcr.Credentials.ApplicationId = APP_ID2;
gcr.Query = Address1;
var myFunc = Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>(gsc.BeginGeocode, gsc.EndGeocode);
gcResp = myFunc(gcr) as GeocodeResponse;
if (gcResp.Results.Count > 0 && gcResp.Results[0].Locations.Count > 0)
{
returnLocation = gcResp.Results[0].Locations[0];
}
return returnLocation as IObservable<Location>;
}
gcResp 返回为 null。任何想法或建议将不胜感激。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您订阅的可观察源是异步的,因此您无法在订阅后立即访问结果。您需要访问订阅中的结果。
更好的是,根本不订阅,只需编写响应:
如果您只需要第一个有效值(地址的位置不太可能更改),则添加
.Take(1)
在Where
和Select
之间。编辑:如果您想专门处理未找到的地址,您可以返回结果并让使用者处理它,也可以返回异常并提供
OnError
订阅时的处理程序。如果您考虑执行后者,则可以使用SelectMany
:The observable source you are subscribing to is asynchronous, so you can't access the result immediately after subscribing. You need to access the result in the subscription.
Better yet, don't subscribe at all and simply compose the response:
If you only need the first valid value (the location of the address is unlikely to change), then add a
.Take(1)
between theWhere
andSelect
.Edit: If you want to specifically handle the address not being found, you can either return results and have the consumer deal with it or you can return an Exception and provide an
OnError
handler when subscribing. If you're thinking of doing the latter, you would useSelectMany
:如果展开
myFunc
的类型,您会看到它是Func>
。因此,当您调用
myFunc(gcr)
时,您得到的是IObservable
,而不是GeocodeResponse
。您的代码myFunc(gcr) as GeocodeResponse
返回null
,因为转换无效。您需要做的是获取可观察值的最后一个值,或者只是进行订阅。调用
.Last()
将阻塞。如果您调用.Subscribe(...)
您的响应将通过回调线程传递。试试这个:
让我知道你进展如何。
If you expand out the type of
myFunc
you'll see that it isFunc<GeocodeRequest, IObservable<GeocodeResponse>>
.So when you call
myFunc(gcr)
you have anIObservable<GeocodeResponse>
and not aGeocodeResponse
. Your codemyFunc(gcr) as GeocodeResponse
returnsnull
because the cast is invalid.What you need to do is either get the last value of the observable or just do a subscribe. Calling
.Last()
will block. If you call.Subscribe(...)
your response will come thru on the call back thread.Try this:
Let me know how you go.
理查德(和其他人),
所以我有返回位置的代码,并且有订阅的调用代码。这是(希望)最后一期。当我调用 GetGPSCooperatives 时,下一条语句将立即执行,而无需等待订阅完成。以下是按钮 OnClick 事件处理程序中的示例。
在订阅外部进行的 Output.Text 赋值在订阅完成之前执行并显示零,然后订阅内部的 1 显示新的位置信息。
此过程的目的是获取位置信息,然后将其保存在数据库记录中,并且我在 Foreach 循环中按顺序处理多个地址。我选择 Rx Extensions 作为解决方案,以避免异步回调作为编码陷阱的问题。但看来我已经把一个陷阱换成了另一个陷阱。
想法、评论、建议?
Richard (and others),
So I have the code returning the location and I have the calling code subscribing. Here is (hopefully) the final issue. When I call GetGPSCoordinates, the next statement gets executed immediately without waiting for the subscribe to finish. Here's an example in a button OnClick event handler.
The Output.Text assignment that takes place outside of Subscribe executes before the Subscribe has finished and displays zeros and then the one inside the subscribe displays the new location info.
The purpose of this process is to get location info that will then be saved in a database record and I am processing multiple addresses sequentially in a Foreach loop. I chose Rx Extensions as a solution to avoid the problem of the async callback as a coding trap. But it seems I have exchanged one trap for another.
Thoughts, comments, suggestions?