简体   繁体   中英

C# Cannot convert from 'void' to 'System.Threading.Tasks.Task

After searching I didn't find a related topic to my problem so here it goes:

Due to the limit of the service we are calling, we plan to fire a pre-defined number of service requests in parallel each time. The code is:

        public static void RunConcurrentThreads(List<Item> list, Action<Item> action, int nNumberOfConcurrentThreads = 3)
    {
        for (int i = 0; i < list.Count; i++)
        {

            var taskList = new List<Task>();

            for (int j = 0; j < nNumberOfConcurrentThreads; j++)
            {
                if (i + j < list.Count)
                {
                    taskList.Add(action(list[i + j]));
                }
                else
                {
                    break;
                }
            }

            if (taskList.Count > 0)
            {
                Task.WaitAll(taskList.ToArray());
            }

            i = i + nNumberOfConcurrentThreads;
        }
    }

The "Item" is a class that defines the object we are dealing with.

"action" is for a void method that take one Item object as parameter. The method will call a service, then save returned information to database. It takes about 0.5 - 1 second to finish.

nNumberOfConcurrentThreads is the number of concurrent requests that will be fired at each time.

This line is giving the error in the title

taskList.Add(action(list[i + j]));

So how to fix the error? Or is there a better way to handle this kind of concurrency problem?

Thank you.

Microsoft has done the work for you with the Task Parallel Library .

Just use Parallel.ForEach and it's simple.

using System.Threading.Tasks;

static void RunConcurrentThreads(List<Item> list, Action<Item> action, int nNumberOfConcurrentThreads = 3)
{
    Parallel.ForEach
    (
        list,
        new ParallelOptions { MaxDegreeOfParallelism = nNumberOfConcurrentThreads  }
        i => action(i)
    );
}

While this looks like a loop, in reality the runtime will create a thread for each iteration (up to the limit specified) and run them in parallel.

Action doesn't return anything. If you want to run it in a Task you need to call Task.Run which starts running the action in a separate thread and returns the task:

taskList.Add(Task.Run(() => action(list[i + j]));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM