【发布时间】:2015-01-02 11:00:09
【问题描述】:
我正在为 WP8 开发并有以下代码
public static async Task<GeoCoordinate> ConvertToGeoCoordinate(String streetAddress)
{
// NOTE: constructor throws invalid cross thread exception
var query = new GeocodeQuery()
{
GeoCoordinate = new GeoCoordinate(0, 0),
SearchTerm = streetAddress,
MaxResultCount = 1,
};
var task = new TaskCompletionSource<GeoCoordinate>();
query.QueryCompleted += (s, ev) =>
{
foreach (var item in ev.Result)
task.TrySetResult(item.GeoCoordinate);
task.TrySetResult(null);
};
query.QueryAsync();
return await task.Task;
}
我对任务、异步、等待和其他东西不太熟悉,但我很确定调用 var res = await ConvertToGeoCoordinate("blabla"); 不应该返回无效的跨线程访问。在互联网的某个地方,我遇到一个人说 GeocodeQuery 需要在 UI 线程上执行,但如果我调用 ConvertToGeoCoordinate("blabla").ContinueWith((x) => {Log(x.Result.ToString();}); 我会得到一个结果,这不是同步执行。
目前我正在做这样的事情(因为它有效)
ConvertToGeoCoordinate(addr1).ContinueWith(() => {
ConvertToGeoCoordinate(addr2).ContinueWith(() => {
ConvertToGeoCoordinate(addr2).ContinueWith(() => {
...
});
});
});
而不是(因为它不起作用)
await ConvertToGeoCoordinate(addr1);
await ConvertToGeoCoordinate(addr2);
await ConvertToGeoCoordinate(addr3);
...
这很尴尬。如何正确使用 GeocodeQuery?有人有这方面的经验吗?
【问题讨论】:
-
但是如果你使用第二种形式——
ConvertToGeoCoordinate(addr1).ContinueWith(()——那么它实际上并没有在后台线程上执行......对吗?好像网上随便找的人说的都是对的。 -
我相信它只是看起来是同步的,但它实际上是一个异步操作。老实说,我不知道......无论如何,有没有解决这个问题的方法?我没有找到任何东西,我不希望 GUI 被阻止并且代码那么丑陋......
-
我不知道,但您是否尝试将
new GeocodeQuery实例化放在 UI 线程上?如果“QueryAsync”部分本身需要绑定 UI,我会感到惊讶。 -
您多次设置结果,它认为结合 await 关键字的线程编组可能会导致您的异常。 TrySetResult 不返回,所以试试: if(tcs.TrySetResult(...)) return;
标签: c# multithreading windows-phone-8 geolocation