2017-07-23 5 views
0

Ich versuche meine erste Xamarin App zu entwickeln.DEADLOCK Xamarin

Ich habe zwei Klassen für einen Web Service: RestClient: die die Anfrage und erhalten Sie die JSON-String Hilfsklasse macht: die die JSON-String bekommen sollte und deserialisiert es zum Objekttyp.

Ich weiß, dass die Wait Methode ist nicht die beste Option, aber ich habe so viele verschiedene vorgeschlagene Versionen versucht, aber es funktioniert nicht. Jeder Versuch endete in einem Deadlock. Jeder Thread arbeitet im Hintergrund. Wie kann ich meine Daten auf die Benutzeroberfläche zurückholen?

Code meiner RestClient Klasse:

class RestClient 
{ 

    public static string base_url = @"our Restservice address"; 
    // public string completeUrl { get; set; } 

    HttpClient client; 

    public RestClient() 
    { 
     client = new HttpClient(); 
     client.BaseAddress = new Uri(base_url); 
     //client.MaxResponseContentBufferSize = 256000; 
    } 

    public async Task<String> GetData(string endpoint) 
    { 
    client.DefaultRequestHeaders.Accept.Clear(); 
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 


    HttpResponseMessage response = await client.GetAsync(endpoint); 
    if (response.IsSuccessStatusCode) 
    { 
     string result = await response.Content.ReadAsStringAsync(); 
     return result; 
    } 
    else 
    { 
     return null; 
    } 
} 

-Code meiner Hilfsklasse

public SupplierHelper() 
{ 
} 
public async Task<Suppliers> getData() 
{ 
    RestClient restClient = new RestClient(); 

    string result = await restClient.GetData("suppliers/13"); 
    return JsonConvert.DeserializeObject<Suppliers>(result); 
} 

-Code meiner VievModelClass

public class AccountViewModel : BaseViewModel 
{ 
    public static SupplierHelper supHelper; 
    public static Suppliers sup; 
    public string Name { set; get; } 
    public string Address { set; get; } 

    public AccountViewModel() 
    { 
     loadSupplier().Wait(); 
    } 

    public async Task loadSupplier() 
    { 
     supHelper = new SupplierHelper(); 
     sup = await supHelper.getData(); 
    } 
} 
+0

wahrscheinlich 'Wait()' verursacht diesen Deadlock. Da Sie keinen Konstruktor * async * erstellen können, denken Sie, dass * Wait * dafür sorgen kann, dass es funktioniert. Nein, ändere deine Logik (Zum Beispiel kannst du diesen Code in eine asynchrone Methode von * AccountViewModel * 'verschieben, wenn (sub == null) auf loadSupplier()') wartet. –

+0

Hallo, Willkommen zu Stackoverflow! Ich empfehle Ihnen, die [Welcome Tour] (https://stackoverflow.com/tour) zu nehmen, um hier Ihren Weg zu kennen (und Ihr erstes Abzeichen auch zu verdienen;)). Um die Chancen auf nützliche Antworten zu verbessern, überprüfen Sie bitte auch, wie Sie fragen können (https://stackoverflow.com/help/asking) und wie Sie [vollständige, minimale und überprüfbare Beispiele] erstellen können (https: // stackoverflow .com/hilfe/mcve). – DarkCygnus

Antwort

0

Task.Run(loadSupplier).Wait(); wird Ihr Problem lösen.
Ihr Deadlock wird durch eine asynchrone Methode verursacht, die versucht, eine Fortsetzung auf dem Thread des Aufrufers auszuführen, aber der Thread des Aufrufers wird blockiert, bis die asynchrone Methode abgeschlossen ist.

+0

Nein, das ist flat-out falsch - [nicht auf async-Code blockieren] (http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html) . – EJoshuaS

+0

Das ist funktioniert. Also was ist los? Weil jemand einen Blogbeitrag geschrieben hat und gesagt hat, ich sollte nicht? Was, wenn ich muss? Wie legacy synchrone Schnittstelle, die ich implementiere? Task.Run schließen Sie fehlerhaften asynchronen Code ein, damit Sie darauf blockieren können. Sicher solltest du es besser nicht in ctor machen, aber das ist nicht die Frage. –

0

.Wait() ist schlimmer als "nicht die beste Option" - In einer Umgebung mit einem Synchronisationskontext wird eine zyklische Wartezeit aktiv ausgelöst. Lesen Sie this article für weitere Details.

Wenn Sie dies aufrufen müssen, um das Objekt korrekt zu initialisieren, können Sie eine asynchrone Factory-Methode oder etwas verwenden.

+1

Stellen Sie eine Lösung zur Verfügung –