Async JSON Deserialization

白昼怎懂夜的黑 提交于 2020-01-09 11:09:32

问题


I need to do a RestRequest and get some JSON, I am not sure if my method is really async since there is still a little freeze in my UI when I use this method.

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

Specially for this line of code :

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

is it really async ? because it seems to block the the UI . Can you tell me how can I make this function properly async ?


回答1:


It seems the delegate passed as an argument to ExecuteAsync is being executed on the UI thread. If that is the case, simply use Task.Run to run the delegate on the threadpool instead.

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

Is List_ a field? It seems to me like it should be a local variable. Also, there's no need to initialize it with an empty list before deserializing the json.




回答2:


JsonConvert.DeserializeObject is synchronous. You can tell by the fact that it returns you the result of its computation immediately. There is no way it could do something "in the background" and only later hand you the result.

Move CPU bound work to a thread-pool thread using Task.Run. You can move the whole REST request there if that is more convenient to you.

Note, that your message box call should run on the UI thread. Better not create a message box on a thread-pool thread like you are doing at the moment. That will result in two UI threads. The message box will not be modal.



来源:https://stackoverflow.com/questions/25014830/async-json-deserialization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!