2013-02-22 2 views
7

Я новичок в C# и использую Task. Я пытался запустить это приложение, но мое приложение зависает каждый раз. Когда я добавляю task.wait(), он продолжает ждать и никогда не возвращается. Буду признателен за любую оказанную помощь. EDIT: Я хочу вызвать DownloadString асинхронно. И когда я выполняю task.Start(), как предложил «Остин Салонен», я не получаю адрес местоположения, но значение по умолчанию в строке местоположения от returnVal. Это означает, что местоположение получило значение, назначенное до завершения задачи. Как я могу убедиться, что после того, как задача будет завершена, тогда местоположение будет присвоено returnVal.Использование приложения Task.wait() зависает и никогда не возвращает

public class ReverseGeoCoding 
     { 
       static string baseUri = "http://maps.googleapis.com/maps/api/geocode/xml?latlng={0},{1}&sensor=false"; 
       string location = "default"; 
       static string returnVal = "defaultRet"; 
       string latitude = "51.962146"; 
       string longitude = "7.602304"; 
       public string getLocation() 
       { 
        Task task = new Task(() => RetrieveFormatedAddress(latitude, longitude)); 
       //var result = Task.Factory.StartNew(RetrieveFormatedAddress("51.962146", "7.602304")); 
        task.Wait(); 
        //RetrieveFormatedAddress("51.962146", "7.602304"); 
        location = returnVal; 
        return location; 
       } 
       public static void RetrieveFormatedAddress(string lat, string lng) 
       { 
        string requestUri = string.Format(baseUri, lat, lng); 

        using (WebClient wc = new WebClient()) 
        { 
         wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted); 
         wc.DownloadStringAsync(new Uri(requestUri)); 
        } 
       } 

       static void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) 
       { 
        var xmlElm = XElement.Parse(e.Result); 

        var status = (from elm in xmlElm.Descendants() 
            where elm.Name == "status" 
            select elm).FirstOrDefault(); 
        if (status.Value.ToLower() == "ok") 
        { 
         var res = (from elm in xmlElm.Descendants() 
            where elm.Name == "formatted_address" 
            select elm).FirstOrDefault(); 
         //Console.WriteLine(res.Value); 
         returnVal = res.Value; 
        } 
        else 
        { 
         returnVal = "No Address Found"; 
         //Console.WriteLine("No Address Found"); 
        } 
       } 
      } 

ответ

2

Не понимаю, почему вы используете DownloadStringCompleted и пытаетесь сделать это блокировки. Если вы хотите ждать результата, просто использовать блокирующий вызов DownloadString

var location = RetrieveFormatedAddress(51.962146, 7.602304); 

string RetrieveFormatedAddress(double lat, double lon) 
{ 
    using (WebClient client = new WebClient()) 
    { 
     string xml = client.DownloadString(String.Format(baseUri, lat, lon)); 
     return ParseXml(xml); 
    } 
} 

private static string ParseXml(string xml) 
{ 
    var result = XDocument.Parse(xml) 
       .Descendants("formatted_address") 
       .FirstOrDefault(); 
    if (result != null) 
     return result.Value; 
    else 
     return "No Address Found"; 
} 

Если вы хотите сделать его асинхронной

var location = await RetrieveFormatedAddressAsync(51.962146, 7.602304); 

async Task<string> RetrieveFormatedAddressAsync(double lat,double lon) 
{ 
    using(HttpClient client = new HttpClient()) 
    { 
     string xml = await client.GetStringAsync(String.Format(baseUri,lat,lon)); 
     return ParseXml(xml); 
    } 
} 
10

На самом деле вы не выполняете задачу. Отладка и проверка task.TaskStatus покажут это.

// this should help 
task.Start(); 

// ... or this: 
Task.Wait(Task.Factory.StartNew(RetrieveFormatedAddress("51.962146", "7.602304"))); 

Хотя, если вы блокируете, зачем начинать с другой темы?

+0

Я хочу назвать DownloadString асинхронно. И когда я делаю task.Start(); Я не получаю адрес местоположения, но значение по умолчанию в строке местоположения от returnVal. Это означает, что местоположение получило значение, назначенное до завершения задачи. Как я могу убедиться, что после того, как задача будет завершена, тогда местоположение будет присвоено returnVal. – PhantomM

+0

@ Аустин, не могли бы вы объяснить, что стоит за этим поведением? то есть код задачи запускается при простом вызове без StartNew, но никогда не возвращается с первого 'ожидания '. –