2017-05-14 29 views
2

Ich habe eine UWP-Anwendung, in der ich versuche, einige Daten aus einer lokalen Textdatei zu speichern und abzurufen, aber egal wie ich es versuche, die Anwendung wird blockiert. Aufgrund von synchronem Zeug, das passieren muss, versuche ich eine Aufgabe zu verwenden und auf ihre Fertigstellung zu warten, aber die Anwendung sperrt trotzdem.Wie löst man diesen Deadlock?

Ich habe eine Seite in meiner UWP Anwendung namens „Mainpage“ und in seinem Konstruktor habe ich den folgenden Code:

var listenkeyViewModel = new ListenkeyViewModel(); 
listenkeyViewModel.GetKey(); 
listenkey = listenkeyViewModel.Listenkey; 

Der get-Schlüssel ist das Problem hier, weil es eine Methode für das Ansichtsmodell nennt (die ich habe synchron zu sein, weil ich den Anruf synchron dachte machen so schnell wie möglich vorzuziehen wäre.

public void GetKey() 
{ 
    try 
    { 
     var listenKeyTask = RetrieveListenKey(); 
     _listenkey = listenKeyTask.Result; 
    } 
    catch (Exception e) 
    { 
    } 
} 

public static async Task<string> RetrieveListenKey() 
{ 
    try 
    { 
     var storageFolder = Windows.Storage.ApplicationData.Current.LocalFolder; 
     var listenkeyFile = await storageFolder.GetFileAsync("listenkey.txt"); 
     return await Windows.Storage.FileIO.ReadTextAsync(listenkeyFile); 
    } 
    catch (Exception e) 
    { 
     throw new Exception("Could not load file"); 
    } 
} 

ich weiß, das Ding „async den ganzen Weg nach unten“, aber das ist hier nicht möglich. ich kann nicht den Konstruktor machen, wo die Der ursprüngliche Code liegt asynchron. Wie geht es Ihnen? soll nicht festgefahren werden? Ich verstehe nicht.

+4

Verschieben Sie den Code vom Konstruktor weg. Fügen Sie eine asynchrone Methode wie 'InitializeAsync' oder was auch immer ein. Es ist die beste Lösung. –

Antwort

3

GetKey Convert/erwarten die Berufung dieses aus dem Konstruktor und in einem Event-Handler

public async Task GetKey() { 
    try { 
     var listenKeyTask = RetrieveListenKey(); 
     _listenkey = await listenKeyTask; 
    } catch (Exception e) { 
     //...should handle/log error 
    } 
} 

Umzug nach Async. wie Seitenladen oder ein anderes Ereignis, das früh im Lebenszyklus der Seite aufgerufen wird.

partial class MainPage : Page { 
    ListenkeyViewModel listenkeyViewModel; 
    string listenkey; 

    public MainPage() { 
     InitializeComponent(); 
     listenkeyViewModel = new ListenkeyViewModel(); 
     // add a handler to be called when the page has been loaded 
     this.Loaded += OnPageLoaded;    
    } 

    async void OnPageLoaded(object sender, RoutedEventArgs e) {    
     await listenkeyViewModel.GetKey(); 
     listenkey = listenkeyViewModel.Listenkey; 
    } 

    // Shown for demonstration purposes only. 
    // This is typically autogenerated by Visual Studio. 
    private void InitializeComponent() { 
    } 
} 

async void auf Event-Handler erlaubt so das das Verfahren ohne Stillstand fließen lassen sollte.