Async JSON Deserializzazione

Ho bisogno di fare un RestRequest e ottenere alcuni JSON, io non sono sicuro se il mio metodo è molto async perché c’è ancora un po ‘ di congelare la mia interfaccia utente quando si utilizza questo metodo.

 public async Task<List<MyObject>> Load() 
            {
                var tcs = new TaskCompletionSource<List<Myobject>>();
                var client = new RestSharp.RestClient("https://exampleapi.com");
                client.Authenticator = OAuth1Authenticator.ForProtectedResource(
           [...]);
                var request = new RestSharp.RestRequest("examp.json", Method.GET);
                client.ExecuteAsync(request, response =>
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        List_ = new List<MyObject>();
                        List_ = JsonConvert.DeserializeObject<List<MyObject>>(response.Content);
                        tcs.SetResult(List_);
                    }
                    else
                    {
                        MessageBox.Show("Error");
                    }
                });
                return await tcs.Task;        
            }

Appositamente per questa linea di codice :

List_ = JsonConvert.DeserializeObject<List<MyObject>>(response.Content);

è davvero async ? perché sembra bloccare l’interfaccia utente . Mi potete dire come posso rendere questa funzione correttamente async ?

 

2 Replies
  1. 8

    Sembra il delegato passato come argomento a ExecuteAsync viene eseguito sul thread UI. Se questo è il caso, è sufficiente utilizzare Task.Run per eseguire il delegato per il threadpool, invece.

    client.ExecuteAsync(request, async (response) =>
        {
            if (response.StatusCode == HttpStatusCode.OK)
            {
                var list = await Task.Run( () => JsonConvert.DeserializeObject<List<MyObject>>(response.Content));
                tcs.SetResult(list);
            }
            else
            {
                MessageBox.Show("Error");
            }
        });

    È List_ un campo? Mi sembra come dovrebbe essere una variabile locale. Inoltre, non c’è bisogno di inizializzare con una lista vuota prima di deserializzazione di json.

    • Grazie ho rimosso l’inizializzazione della mia Lista e, in generale, come faccio a sapere se un’operazione viene eseguita sul mio Thread dell’interfaccia utente ?
    • Per essere onesti, io non so molto su Windows Phone API, ma ecco un semplice test: Aggiungere Thread.Sleep(5000) ed eseguire il codice, se si blocca l’interfaccia utente, quindi eseguito sul thread UI.
    • Ok grazie si mi ricordo di che !
  2. 3

    JsonConvert.DeserializeObject è sincrono. Si può dire, dal fatto che essa restituisce il risultato del suo calcolo immediatamente. Non c’è modo si potrebbe fare qualcosa “in background” e, solo successivamente, a mano il risultato.

    Spostare sulla CPU un thread del pool di thread che utilizza Task.Run. È possibile spostare tutto il RESTO, a richiesta, se è più conveniente per te.

    Nota, che la vostra casella di messaggio di chiamata deve essere eseguito sul thread UI. Meglio non creare una finestra di messaggio in un thread del pool di thread come si sta facendo al momento. Che si tradurrà in due UI thread. Il messaggio di dialogo non modale.

    • Grazie, voglio cambiare il mio MessageBox, ma come faccio a tel se un’operazione viene eseguita sul thread UI o no?
    • Che di solito è documentato. Sono sicuro che RestSharp documenti su qual è il filo che la richiamata verrà eseguita.

Lascia un commento