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

时间:2018-09-04 20:10:55

标签: c# concurrency

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.

2 个答案:

答案 0 :(得分:3)

Microsoft已通过Task Parallel Library为您完成了工作。

只需使用Parallel.ForEach,就很简单。

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)
    );
}

虽然这看起来像一个循环,但实际上,运行时将为每次迭代创建一个线程(达到指定的限制)并并行运行它们。

答案 1 :(得分:2)

Action不返回任何内容。如果要在Task中运行它,则需要调用Task.Run,它开始在单独的线程中运行该操作并返回任务:

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