2015-01-02 93 views
1

我开发WP8和有下面的代码无效跨线程访问Windows Phone上

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正确执行此操作?有没有人有这方面的经验?

+0

但如果使用第二种形式 - - 'ConvertToGeoCoordinate(addr1).ContinueWith(()' - 那么它不会在后台线程上实际执行......对吗?看起来就像互联网上的随机人员是正确的。 – McGarnagle

+0

我相信它只看起来是同步的,但它是真的是一个异步操作,老实说,我不知道......反正有没有解决这个问题的方法?我没有找到任何东西,我不希望GUI被阻止和代码是这样丑陋的...... – xmashallax

+1

我不知道,但你尝试只是在UI线程上的'新的GeocodeQuery'实例化?如果“QueryAsync”部分本身需要用户界面绑定,我会感到惊讶。 – McGarnagle

回答

0

GeocodeQuery只能在主/ UI线程上创建。确保仅从主/ UI线程调用ConvertoToGeocoordinate方法。

例如,你可以使用调度:

Dispatcher.BeginInvoke(async() => { ... }); 

(我想你确切的代码,并从UI线程调用,当它工作正常的await。)

相关问题