2013-02-22 2 views
7

Ich bin neu in C# und mit Task. Ich habe versucht, diese Anwendung auszuführen, aber meine Anwendung hängt jedes Mal. Wenn ich task.wait() hinzufüge, wartet es und kehrt nie zurück. Jede Hilfe wird sehr geschätzt. EDIT: Ich möchte DownloadString asynchron aufrufen. Und wenn ich task.Start() mache, wie von "Austin Salonen" vorgeschlagen, bekomme ich nicht die Adresse des Ortes, sondern den Standardwert in der Ortszeichenkette von returnVal. Dies bedeutet, dass dem Standort ein Wert zugewiesen wurde, bevor die Aufgabe abgeschlossen wurde. Wie kann ich sicherstellen, dass nach Abschluss der Aufgabe nur dann der Standort returnVal zugewiesen wird.Verwendung von Task.wait() Anwendung hängt und nie zurück

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

Antwort

2

Ich verstehe nicht, warum Sie DownloadStringCompleted Ereignis verwenden und versuchen, es Blockierung zu machen. Wenn Sie das Ergebnis warten wollen, verwenden Sie einfach Anruf 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"; 
} 

blockiert Wenn Sie es async

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

Sie führen die Aufgabe nicht tatsächlich aus. Debugging und Überprüfung task.TaskStatus würde dies zeigen.

// this should help 
task.Start(); 

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

Obwohl, wenn Sie blockiert, warum ein anderer Thread beginnen zu beginnen?

+0

ich DownloadString Asynchron machen wollen anrufen möchten. Und wenn ich task.Start(); Ich bekomme nicht die Adresse des Ortes, sondern den Standardwert in der Positionsstring von returnVal. Dies bedeutet, dass dem Standort ein Wert zugewiesen wurde, bevor die Aufgabe abgeschlossen wurde. Wie kann ich sicherstellen, dass nach Abschluss der Aufgabe nur dann der Standort returnVal zugewiesen wird. – PhantomM

+0

@Austin, können Sie bitte erklären, was hinter diesem Verhalten steckt? d.h. der Code der Aufgabe wird ausgeführt, wenn er einfach ohne StartNew aufgerufen wird, kehrt jedoch niemals vom ersten "Warten" zurück. –

Verwandte Themen