2013-02-22 10 views
7

Sono nuovo in C# e utilizzo Task. Stavo cercando di eseguire questa applicazione, ma la mia applicazione si blocca ogni volta. Quando aggiungo task.wait(), continua ad aspettare e non ritorna mai. Ogni aiuto è molto apprezzato. MODIFICA: Voglio chiamare DownloadString in modo asincrono. E quando sto facendo task.Start() come suggerito da "Austin Salonen" Non ottengo l'indirizzo di posizione, ma il valore di default nella stringa di posizione da returnVal. Significa che la posizione ha il valore assegnato prima che l'attività sia completata. Come posso assicurarmi che dopo che l'attività è stata completata solo allora la posizione viene assegnata a returnVal.L'utilizzo dell'applicazione Task.wait() si blocca e non restituisce mai

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"); 
        } 
       } 
      } 

risposta

2

Non capisco perché si utilizzi l'evento DownloadStringCompleted e si provi a farlo bloccando. Se si vuole attendere il risultato, basta usare blocco di chiamata 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"; 
} 

Se si vuole rendere asincrona

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

In realtà non si sta eseguendo l'operazione. Debug e controllo task.TaskStatus mostrerebbero questo.

// this should help 
task.Start(); 

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

Anche se stai bloccando, perché iniziare un'altra discussione per iniziare?

+0

Voglio chiamare DownloadString in modo asincrono. E quando sto facendo task.Start(); Non ottengo l'indirizzo di posizione ma il valore di default nella stringa di posizione da returnVal. Significa che la posizione ha il valore assegnato prima che l'attività sia completata. Come posso assicurarmi che dopo che l'attività è stata completata solo allora la posizione viene assegnata a returnVal. – PhantomM

+0

@ Austin, puoi spiegare cosa c'è dietro questo comportamento? Il codice dell'attività viene eseguito quando viene semplicemente chiamato senza StartNew, ma non ritorna mai dal primo 'await'. –

Problemi correlati