我怎么能等到十个任务完成然后执行接下来的十个任务

时间:2014-06-08 13:34:54

标签: c# task

我正在访问具有请求限制的Web服务,您可以每分钟进行一次。我必须访问X> 10个条目,但我只允许每分钟10个。

我将服务实现为Singleton,可以从代码的不同部分访问。现在我需要一种方法来了解,已经提出了多少请求以及是否允许我创建一个新请求。

因此我制作了一个示例代码,增加了100个任务。每个任务都有3秒的延迟,只有在使用Task之前还有10个任务之后才能执行Task.WhenAny。但是我得到了一个" An exception of type 'System.InvalidOperationException' occurred in mscorlib.dll but was not handled in user code"从列表中删除已完成的任务时出现异常。

我该如何解决这个问题?

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

namespace ConsoleApplication1
{
    class Test
    {
        private static Test instance;
        public static Test Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new Test();
                }
                return instance;
            }
        }


        private List<Task> taskPool = new List<Task>();
        private Test()
        {

        }

        public async void AddTask(int count)
        {
            // wait till less then then tasks are in the list
            while (taskPool.Count >= 10)
            {
                var completedTask = await Task.WhenAny(taskPool);
                taskPool.Remove(completedTask);
            }

            Console.WriteLine("{0}, {1}", count, DateTime.Now);

            taskPool.Add(Task.Delay(TimeSpan.FromSeconds(3)));
        }
    }
}

1 个答案:

答案 0 :(得分:2)

一个好老的信号量解决了我的问题。这是一个经典的线程问题,有一些经过测试的概念如何解决它,这就是我正在使用的那个:

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

namespace ConsoleApplication1
{
    class Test
    {
        private static Test instance;
        public static Test Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new Test();
                }
                return instance;
            }
        }

        private static Semaphore _pool = new Semaphore(0, 10);
        private Test()
        {
            _pool.Release(10);
        }

        public async void AddTask(int count)
        {   
            _pool.WaitOne();
            var task = Task.Delay(TimeSpan.FromSeconds(3));
            Console.WriteLine("{0}, {1}", count, DateTime.Now);
            await task;
            _pool.Release();
        }
    }
}