2013-02-22 13 views
7

Jestem nowy w języku C# i używam Task. Próbowałem uruchomić tę aplikację, ale moja aplikacja zawiesza się za każdym razem. Kiedy dodaję task.wait(), wciąż czeka i nigdy nie wraca. Każda pomoc jest doceniana. EDYTOWANIE: Chcę wywołać Asynchronicznie DownloadString. I kiedy robię task.Start() jak sugeruje "Austin Salonen", nie otrzymuję adresu lokalizacji, lecz wartość domyślną w łańcuchu lokalizacji z returnVal. Oznacza to, że lokalizacja otrzymała wartość przypisaną przed ukończeniem zadania. Jak mogę się upewnić, że po wykonaniu zadania tylko wtedy lokalizacja zostanie przypisana do zwrotu.Korzystanie z aplikacji Task.wait() zawiesza się i nigdy nie wraca

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

Odpowiedz

2

Nie rozumiem, dlaczego używasz zdarzenia DownloadStringCompleted i próbujesz zablokować blokowanie. Jeśli chcesz czekać na wynik, wystarczy użyć blokowanie połączeń 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"; 
} 

jeśli chcesz zrobić to asynchroniczny

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

W rzeczywistości nie wykonujesz zadania. Debugowanie i sprawdzanie pokazałoby to.

// this should help 
task.Start(); 

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

Ale jeśli blokujesz, po co rozpoczynać kolejny wątek?

+0

chcę zadzwonić DownloadString asynchronicznie. A kiedy robię task.Start(); Nie otrzymuję adresu lokalizacji, ale wartość domyślna w ciągu lokalizacji z returnVal. Oznacza to, że lokalizacja otrzymała wartość przypisaną przed ukończeniem zadania. Jak mogę się upewnić, że po wykonaniu zadania tylko wtedy lokalizacja zostanie przypisana do zwrotu. – PhantomM

+0

@Austin, czy możesz wyjaśnić, co kryje się za tym zachowaniem? tj. kod zadania uruchamia się, gdy po prostu zostanie wywołany bez StartNew, ale nigdy nie wróci z pierwszego 'await'. –

Powiązane problemy