2

I am new to the async world of C# and admittedly don't have a lot of knowledge on the subject. I just had to implement it in one of our services and I am a little confused on how it works. I want to POST to an API as fast as absolutely possible. I'm less interested in how long it takes to get the response and do stuff with it. Here's an example of what I'm doing.

        foreach (var item in list)
        {
            callPostFunction(item.data);
            log("Posted");
        }

    public async void callPostFunction(PostData data)
    {
        var apiResult = await postToAPI(data);
        updateDB(apiResult);
    }

    public static async Task<string> postToAPI(PostData dataToSend)
    {
        var url = "Example.com";

        HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create(url);
        ASCIIEncoding encoding = new ASCIIEncoding();
        string postData = dataToSend;
        byte[] dataBytes = encoding.GetBytes(postData);

        httpWReq.Method = "POST";
        httpWReq.ContentType = "application/x-www-form-urlencoded";
        httpWReq.ContentLength = dataBytes.Length;
        httpWReq.Accept = "application/json, application/xml, text/json, text/x-json, text/javascript, text/xml";

        using (var stream = await httpWReq.GetRequestStreamAsync())
        {
            await stream.WriteAsync(dataBytes, 0, dataBytes.Length);
        }

        HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();

        return new StreamReader(response.GetResponseStream()).ReadToEnd();
    }

What happens is if I put 1000 items in the list, "Posted" is logged 1000 times immediately. Great, the process is done and can continue doing other things. The problem is the somewhere in the background the callPostFunction is calling postToAPI and posting to the API, it works, but it takes a long time. It takes about as long (although not as long) as it did before implementing async. I feel like I'm missing something.

I have to hit the API as fast. Ideally I'd like to hit it as often as the callPostFunction is getting called, nearly immediately. How might I go about doing that?

3
  • 5
    Having an async void method, unless it's a method at the very top of your stack, is usually a flawed design. Commented Mar 7, 2014 at 20:52
  • In this example, though, how would I allow my process (the foreach) to keep running through records as fast as possible. If the callPostFunction returned something, wouldn't the call to it have to await it? Commented Mar 7, 2014 at 20:55
  • 1
    No, it would not have to await it, or at least not right away. Generally what you would expect to see is something like await Task.WhenAll(tasksForEachIndividualRequest);. You'd then do any wrap up, logging, or whatever else after that. And if you really don't want to do that, you can still call the method and just ignore the task, but by having the method return a task it means that if some other caller of this method somewhere else does want to await it, it can. By making it void you're saying that nobody, ever, at any time, will need to await it. Commented Mar 7, 2014 at 20:57

2 Answers 2

5

Set ServicePointManager.DefaultConnectionLimit to int.MaxValue.

Also, as @Servy pointed out, avoid async void.

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

Comments

4

You're not missing something. It takes time to post a bunch of data. Network connections are slow. They have limited bandwidth. Doing this work asynchronously is no magic bullet for speed. It's purpose is not to optimize speed either.

3 Comments

+1, but I think your answer needs to (hopefully) include what your comment said above about the top of the stack and the fact that this is pretty crucial to avoid saturation. :)
@Moo-Juice That's unrelated to the actual question asked though. It's an interesting tangent, but still offtopic from the question at hand, which is why it's in a comment, instead of the answer.
Fair point, tangents are somewhat frowned upon :) Good answer, however.

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.