2013-03-28 277 views
1

我有一個關於異步方法如何在c#上工作的問題。我正在嘗試獲取convertAddressToCoordinate方法來將myLocation變量設置爲GeoCoordinate。但是,即使在myLocation值設置之前,也會調用compareDistance方法。如何在調用compareDistance()之前確保myLocation值不爲null?等待異步操作完成

public GeoCoordinate myLocation = null; 

public void returnClosestCurrent(string address) 
{ 

    convertAddressToCoordinate(address); 
    compareDistance(myLocation); 

} 

public void convertAddressToCoordinate(string add) 
{ 
    WebClient wc = new WebClient(); 
    wc.DownloadStringCompleted += wc_DownloadStringCompleted; 
    wc.DownloadStringAsync(new Uri("http://maps.googleapis.com/maps/api/geocode/json?address=1600+bay+st&sensor=false")); 


} 

void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) 
{ 

    XDocument xdoc = XDocument.Parse(e.Result, LoadOptions.None); 

    var data = from query in xdoc.Descendants("location") 
       select new Location 
       { 
        lat = (string)query.Element("lat"), 
        lng = (string)query.Element("lng") 
       }; 

    GeoCoordinate destinationGeo = new GeoCoordinate(Convert.ToDouble(data.ElementAt(0).lat), Convert.ToDouble(data.ElementAt(0).lng)); 

    myLocation = destinationGeo; 


} 

回答

2

可以使用的await關鍵字用於獲取異步任務的值

http://msdn.microsoft.com/en-us/library/vstudio/hh156528.aspx

+0

我會在哪裏放置await關鍵字在代碼中呢? DownloadStringAsync()沒有返回類型。 – 2013-03-28 01:28:28

+1

我認爲更好的方法是在下載字符串事件中移動'compareDistance'方法 – 2013-03-28 01:31:36

1

看你的代碼,在我看來,在compareDistance(myLocation);只應在wc_DownloadStringCompleted方法結束時調用。

之後,一切都應該正常工作。

1

你會想awaitwc.DownloadStringAsync

public async Task returnClosestCurrent(string address) 
{ 
    await convertAddressToCoordinate(address) 
       .ContinueWith(t => compareDistance(myLocation)); 
} 

public async Task convertAddressToCoordinate(string add) 
{ 
    WebClient wc = new WebClient(); 
    wc.DownloadStringCompleted += wc_DownloadStringCompleted; 
    await wc.DownloadStringAsync(new Uri("http://maps.googleapis.com/maps/api/geocode/json?address=1600+bay+st&sensor=false")); 
} 

async/await模式是代碼往往把一切都變成async/await

它可以進行重構使用WebClient.DownloadStringTaskAsync

public async Task ReturnClosestCurrent(string address) 
{ 
    await convertAddressToCoordinate(address) 
      .ContinueWith(t => compareDistance(t.Result)); 
} 

public async Task<GeoCoordinate> ConvertAddressToCoordinate(string add) 
{ 
    WebClient wc = new WebClient(); 
    wc.DownloadStringCompleted += wc_DownloadStringCompleted; 
    var content = await wc.DownloadStringTaskAsync(new Uri("http://maps.googleapis.com/maps/api/geocode/json?address=1600+bay+st&sensor=false")); 

    return ParseContent(content); 
} 

private GeoCoordinate ParseContent(string content) 
{ 
    XDocument xdoc = XDocument.Parse(content, LoadOptions.None); 

    var data = from query in xdoc.Descendants("location") 
      select new Location 
      { 
       lat = (string)query.Element("lat"), 
       lng = (string)query.Element("lng") 
      }; 

    GeoCoordinate destinationGeo = new GeoCoordinate(Convert.ToDouble(data.ElementAt(0).lat), Convert.ToDouble(data.ElementAt(0).lng)); 

    return destinationGeo; 
} 
+0

對於Windows Phone 8,顯然DownloadStringTaskAsync不存在! – 2013-04-01 03:18:08

+0

有一個[nuget包](http://nuget.org/packages/Microsoft.Bcl.Async/)。 – Romoku 2013-04-01 08:07:05