问题
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