2

I am new to Async/Await. I have to call api and sace result into a txt file. I used webclient.OpenRead and was able to save the file. I want to run my code with multiple inputs to API and I would like to run it in parallel.

For sequential operation I used WebClient.OpenRead() as code works.

class Program
{
    static void Main(string[] args)
    {
        var name = "test1";
        var filename = $"c:\\temp\\{name}.txt";
        var url = $"https://testapi?name eq '{name}')";
        using (var client = new WebClient())
        {
            using (Stream stream = client.OpenRead(url))
            using (StreamReader streamReader = new StreamReader(stream))
            using (JsonTextReader reader = new JsonTextReader(streamReader))
            {
                reader.SupportMultipleContent = true;
                var serializer = new JsonSerializer();
                var parsedData = serializer.Deserialize(reader).ToString();
                File.WriteAllText(filename, parsedData);
                Console.WriteLine($"Result save at {filename}");
            }
        }
    }
}

For parallel operation I tried to utilize WebClient.OpenReadAsync() but my code is not saving the file in c:\temp\

static void Main(string[] args)
        {

            var names = new string[] { "test1", "test2" };
            foreach (var name in names)
            {
                var filename = $"c:\\temp\\{name}.txt";
                 var url = $"https://testapi?name eq '{name}') ";
                var client = new WebClient();
                client.OpenReadCompleted += (sender, e) =>
                {
                    Stream reply = (Stream)e.Result;
                    StreamReader s;
                    s = new StreamReader(reply);
                    using (JsonTextReader reader = new JsonTextReader(s))
                    {
                        reader.SupportMultipleContent = true;
                        var serializer = new JsonSerializer();
                        var parsedData = serializer.Deserialize(reader).ToString();
                        File.WriteAllText(filename, parsedData);
                        Console.WriteLine($"Result save at {filename}");
                    }
                };
                client.OpenReadAsync(new Uri(url));
            }
        }

What is wrong with my code? Any pointers?

1 Answer 1

4

Below is the code which will parallel your tasks. Notice that I don't use foreach loop, which in your case would mean sequential tasks execution. The important part is that first I create a list of tasks which should be executed, then I create a single task with Task.WhenAll by wrapping a list of tasks and then I await the end of the task with .Wait();

Also, read about .Wait(). and how it behaves. It effectively blocks the thread of the application, which can be not desired in more complicated applications.

static void Main(string[] args)
{
    var tasks = new[] {"test1", "test2"}.Select(SaveData);
    Task.WhenAll(tasks).Wait();
}

private static async Task SaveData(string fileName)
{
    var filename = $"c:\\temp\\{fileName}.txt";
    var url = $"https://testapi?name eq '{fileName}') ";
    var client = new WebClient();

    client.OpenReadCompleted += (sender, e) =>
    {
        var reply = e.Result;
        StreamReader s;
        s = new StreamReader(reply);
        using (var reader = new JsonTextReader(s))
        {
            reader.SupportMultipleContent = true;
            var serializer = new JsonSerializer();
            var parsedData = serializer.Deserialize(reader).ToString();
            File.WriteAllText(filename, parsedData);
            Console.WriteLine($"Result save at {fileName}");
        }
    };

    await client.OpenReadTaskAsync(new Uri(url));
}
Sign up to request clarification or add additional context in comments.

1 Comment

thanks for your response. It works. Ocassionally, I get error from e.Result as {"The remote server returned an error: (500) Internal Server Error."}. This could be from the service.

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.