Reputation: 47861
My motivation for this question is because I am creating a .net web API project that would be using an existing neo4j rest api client that has synchronous methods. I'd like to take advantage of some of the performance gains by going to asynchronous methods, but I want to avoid going into the neo4j api library and refactoring the synchronous methods to return async methods. I was wondering if wrapping the calls to the synchronous methods in an await Task.Run() would be beneficial at all. Specifically, what happens in the first example when the async result from httpClient calls the Wait() method, but the whole thing is wrapped in another await.
Also keep in mind that I would be running this on AppHarbor cloud with what I believe is a single virtual core.
So is the following
//what happens with the synchronous rest api client I am using
HttpResponseMessage SendHttpRequest(HttpRequestMessage request)
{
var requestTask = httpClient.SendAsync(request);
requestTask.Wait();
return requestTask.Result;
}
object result = await Task.Run(() =>
{
return SendHttpRequest(request);
});
similar in performance to
return httpClient.SendAsync(request)
Upvotes: 3
Views: 2406
Reputation: 456387
I'd like to take advantage of some of the performance gains by going to asynchronous methods, but I want to avoid going into the neo4j api library and refactoring the synchronous methods to return async methods.
Sorry, you lose all the benefits of async
on the server side if you just wrap synchronous code in Task.Run
.
async
is good on servers because asynchronous operations scale better than threads. But if you're using Task.Run
, then you're using a thread anyway.
Upvotes: 8
Reputation: 7421
The difference is that the Task.Run method simply runs the same blocking code on the threadpool. This means that while it won't block your calling thread, it will block the execution thread.
How much this matters is entirely down to resources and performance considerations.
If the SendHttpRequest method truly is simply waiting on the httpClient.SendAsync Task you could simply avoid that method and write:
object result = await httpClient.SendAsync(request);
Or:
object result = await Task.Run(async () => await httpClient.SendAsync(request));
If the SendAsync task still should be run on a separate thread.
Upvotes: 3