Reputation: 45
I have a ServiceInvoker which calls a Web API (POST endpoint)
public async Task<HttpResponseMessage> InvokeService(string url, string action)
{
string requestUri = @"api/MyController/" + action;
HttpResponseMessage response;
HttpClientHandler handler = new HttpClientHandler()
{
UseDefaultCredentials = true
};
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
response =await client.PostAsJsonAsync(requestUri, myObj);
}
return response;
}
When I debug, after the PostAsJsonAsync
executes, the control goes to main()
. Also without debugging I am not able to hit the service. It works when I do this
response =client.PostAsJsonAsync(requestUri, myObj).Result;
but its synchronous.
This method is called from main()
void main()
{
Start()
}
public void Start()
{
Process();
}
public async Task Process()
{
HttpResponseMessage servResponse;
servResponse=await InvokeService("http://myServiceUrl","myAction");
}
My requirement is to make huge number of calls to Service from different applications. I want to make the call async to improve performance.
Upvotes: 1
Views: 1590
Reputation: 236268
You are not waiting for Process()
complete execution - you just fire async operation, forget about it and return:
Process();
You should wait for task completion. E.g.
Process().Wait();
Application terminates when it's main thread terminates. It doesn't matter how many background threads you have. They all will be killed automatically when main thread terminated. So, you have two options to keep your application alive while background threads are doing their job:
Let's think about first option. If there are many background threads, then you will have multithreaded asynchronous application. Main thread is blocked, but there are many other threads doing their job in parallel. But what if you have single background thread? Main thred is waiting to it, and you have multithreaded synchronous application. That's your case.
Now second option. Doing something on main thread while background threads are executing - is the point of using async operations. But your application has nothing to do on main thread. Of course you can simulate some work. Even with things like
Process(); // fire and forget
while (true); // make your main thread busy
That will make your application multithreaded and asynchronous. But Main thread will be just busy with consuming CPU resources. Nothing else. If you would have something real to do on your main thread:
var task = Process();
DoSomeRealJobHere();
task.Wait(); // still you need to wait for background task
Or if you want application to be more interactive
var task = Process();
do
{
DoSomethingHere(); // e.g display current weather info
} while (!task.IsCompleted);
Note: if you are using async operations, consider to provide option for canceling them by passing CancelationToken.
Upvotes: 2