1

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.

1 Answer 1

2

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:

  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.

Sign up to request clarification or add additional context in comments.

5 Comments

but if its a "fire and Forget" then the "fire" is not hitting my service.
@fz8975 because its also and return - application terminates before request is sent. Seems like simple return is faster than creating http client, generating request and sending it over network
@fz8975 - as I think Stephen Cleary once wrote, you should usually think of "fire and forget" as "fire and crash" (I might be paraphrasing a little).
After adding Wait() its behaviour is synchronous. My service is inserting records incrementaly. What should I do ?
@fz8975 I have updated answer with more details and explanation. But your code do not insert records incrementally. If you have some other code, please consider asking new question about that code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.