我正在访问具有请求限制的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)));
}
}
}
答案 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();
}
}
}