简体   繁体   中英

PostAsJsonAsync not sending request when awaited

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.

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. Eg

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:

  1. Stop main thread and wait for background threads.
  2. Do some job on main thread while background threads are executing.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM