0

I made a function like this:

public void GetData(string dataToPost)
{
    var url = "some URL";

    using (var client = new WebClient())
    {
        client.Headers[HttpRequestHeader.ContentType] = "application/json";

        client.UploadStringCompleted += (s, e) =>
            {
                Console.WriteLine("Result is here");
                Console.WriteLine(e.Result);
            };

        client.UploadStringAsync(new System.Uri(url), "POST", dataToPost);
    }
}

The problem here is the fact that I want to get a value returned from the server (HTTP response).

I want my function to be asynchronous, so for example I'd like to be able to call it 5 times in a loop, without waiting for each call to return something before next call.

I have no idea how to achieve it. I tried to create some Task object to await it, but Task requires a delegate and I don't know what delegate i could give it.

Te function above uses an event, which is fired when the result comes - so I need to return that result.

How can I do that?

6
  • It's a console app. I'm quite new to all this, so I'm not sure if I understand what you mean. UploadStringAsync returns void. //edit Looks like someone deleted his comment Commented Jul 27, 2017 at 10:43
  • Sorry, I thought you were using HttpClient. You need to subscribe to the UploadStringCompleted event which will be called once the call completes. Commented Jul 27, 2017 at 10:45
  • 2
    Would it be possible to switch to HttpClient as this has native async/await support, like msdn.microsoft.com/en-us/library/hh138242.aspx. Commented Jul 27, 2017 at 10:46
  • @Igor, it doesn't matter for me, if you know a way to do it with HttpClient, I can use it Commented Jul 27, 2017 at 10:46
  • In that case see this previous question/answer: stackoverflow.com/a/15176685/1260204 Commented Jul 27, 2017 at 10:48

2 Answers 2

2

WebClient has an overload that returns a Task<string>:

https://msdn.microsoft.com/en-us/library/hh193920(v=vs.110).aspx

You can fire all your requests and then wait for them with Task.WhenAll:

public void GetData(string dataToPost)
{
    var url = "some URL";
    var url2 = "some other URL";

    using (var client = new WebClient())
    {
        client.Headers[HttpRequestHeader.ContentType] = "application/json";

        var task1 = client.UploadStringTaskAsync(new System.Uri(url), "POST", dataToPost);
        var task2 = client.UploadStringTaskAsync(new System.Uri(url2), "POST", dataToPost);

        var results = Task.WhenAll(task1, task2).Result;

        foreach (var result in results)
        {
            Console.WriteLine("Result is here");
            Console.WriteLine(result);
        }
    }
}

Even better if you can change your GetData to be an async method, you can just await on Task.WhenAll

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

Comments

1

As already been said in comments, HttpClient is more natural choice for such tasks. However, you still may wonder how to provide a task subscribed for an event, and that could be done with TaskCompletionSource<T>, with quite small changes to your code:

private Task<string> GetData(string dataToPost)
{
    var url = "some URL";
    var resultSource = new TaskCompletionSource<string>();

    using (var client = new WebClient())
    {
        client.Headers[HttpRequestHeader.ContentType] = "application/json";

        client.UploadStringCompleted += (s, e) => {
            Console.WriteLine("Result is here");
            Console.WriteLine(e.Result);

            // this will complete the task
            resultSource.SetResult(e.Result);
        };

        client.UploadStringAsync(new System.Uri(url), "POST", dataToPost);
    }

    return resultSource.Task;
}

You can also set a cancellation (with a given token too) and exception (even with multiple exceptions) in this case, so it will naturally fit to your needs. All three methods can be done in Try* fashion for the cases of concurrent event subscription.

Also note the @Stefanod'Antonio' answer for an async method overload.

2 Comments

Thanks for your input, that's interesting. Looks to me like a Promise of JavaScript.
Task in C# and Promise in Javascript are nearly equivalent.

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.