Run multiple tasks (variable number) in parallel and continue when done

I need to start the "number" of tasks (variable, but less than 10) not in parallel, and wait for them to complete, getting the result from each. I get the result from each one by storing it in a list and then using it at the end.

Here's my code and it works, but I think there should be a cleaner way to do it.

CALLING TASK NUMBER

List<String> Arguments = new List<String> { "AA", "BB", "CC" }; 

List<String> ResultList = new List<String>();  

//**AT LEAST I'VE GOT ONE**

Task<String> Tasks = Task<String>.Factory.StartNew(() =>
{
    return DoSomething(Arguments[0]);
});

ResultList.Add(Tasks.Result);

for (Int32 i = 1; i < Arguments.Count; i++)
{
    ResultList.Add(Tasks.ContinueWith<String>(Result =>
    {
        return DoSomething(Arguments[i]);

    }).Result);
}

//**DO I NEED THIS?? It working even without!!**
//Tasks.Wait();

for (Int32 i = 0; i < ResultList.Count; i++)
{
    textBox1.AppendText(ResultList[i] + Environment.NewLine + Environment.NewLine);
}

      

+3


source to share


4 answers


You don't need a challenge Wait()

. Documentation for Task <T>. Result :



The get accessor blocks the calling thread until the asynchronous operation completes; this is equivalent to calling the Wait method.

+1


source


I think this is what you are trying to do: for example start the whole batch of parallel tasks and wait for them to complete before continuing



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UnitTestProject2
{
    class Class4
    {
        public void run()
        {
            List<String> Arguments = new List<String> { "AA", "BB", "CC" };
            List<Task<String>> tasks = new List<Task<string>>();

            foreach (string arg in Arguments)
            {
                    tasks.Add(
                        this.DoSomething(arg)
                        .ContinueWith(t => this.DoSomething(t.Result))
                        .Unwrap<string>()
                    );
            }

            Task.WaitAll(tasks.ToArray());

            foreach(Task<string> t in tasks)
            {
                textBox1 += (t.Result + Environment.NewLine + Environment.NewLine);
            }

        }

        public async Task<string> DoSomething(string arg)
        {
            return arg;
        }

        public string textBox1;
    }
}

      

+2


source


you can use async await

public async List<String> SomeMethod() {
   List<String> Arguments = new List<String> { "AA", "BB", "CC" }; 
   List<String> ResultList = new List<String>();  
   foreach(var argument in Arguments) 
   {
     var result = await DoSomething(argument);
     ResultList.Add(result);
   }
   return ResultList;
}

      

0


source


All your code is running synchronously at the moment. You create Task

and then actively block it using Task.Result

.

If you really understand what parallelism is and you really need to do as many tasks as you have arguments in your list, then you can unload all of them and then wait asynchronously (that's the key, being asynchronous) upon completion:

var arguments = new[] { "A", "B", "C" };
var tasks = arguments.Select(argument => Task.Run(() => DoSomething(argument))).ToList();

while (tasks.Count > 0)
{
    var finishedTask = await Task.WhenAny(tasks);
    textBox1.AppendText(string.Format("{0}{1}{1}", finishedTask.Result,
                                                   Environment.NewLine));

    tasks.Remove(finishedTask);
}

      

Edit: From your comments:

I am calling a web api (not mine) which does not allow me to call multiple times in parallel, so I need to wait for each task to complete

Then you don't need a stream for every argument at all. Two things:

  • You can make the call completely synchronous since you have to wait for each call to complete. Using threadpool threads for this is simply useless
  • You can make asynchronous calls without having to use threads at all. Look at HttpClient

    its methods XXXAsync

    (for example GetAsync

    ).
0


source







All Articles