0

是否可以在流和其他一些标准上都有一个BlockingCollection<T>JobQueue在我的例子中)块执行?GetConsumingEnumerable()

我的条件availableSlots > 0是只允许在有可用插槽时消耗物品。问题是当集合中有项目但条件为假时,foreach 无限循环。

我不能让收藏也被阻止availableSlots > 0吗?

foreach (var job in JobQueue.GetConsumingEnumerable())
{
    if(availableSlots > 0)
    {
        JobHandler jobHandler = job;

        Task.Factory.StartNew(() =>
        {
            ExecuteJob(jobHandler);
        });
    }
}

也许我错误地使用了这个集合。任何帮助表示赞赏!

4

2 回答 2

2

如果要在值为 0 时阻止,则需要为此进行额外的同步。我认为适合您的解决方案是SemaphoreSlim,因为它完全符合您的需要:在其值为 0 时等待。

这样,代码将类似于:

SemaphoreSlim slotsSemaphore = new SemaphoreSlim(…);

…

foreach (var job in JobQueue.GetConsumingEnumerable())
{
    slotsSemaphore.Wait();

    JobHandler jobHandler = job;

    Task.Factory.StartNew(() =>
    {
        try
        {
            ExecuteJob(jobHandler);
        }
        finally
        {
            slotsSemaphore.Release();
        }
    });
}
于 2013-10-01T08:50:04.160 回答
0

不确定这是最好的方法,但提出我的选择。

为什么不等到它成真呢?

while (availableSlots <= 0)
{
    Thread.Sleep(1);//arbitary sleep
}

JobHandler jobHandler = job;
...

或使用SpinWait

SpinWait.SpinUntil(() => availableSlots > 0);

JobHandler jobHandler = job;
...

第三种选择是使用ManualResetEventAutoResetEvent

signal.Waitone();

JobHandler jobHandler = job;
...

signal在更改 的值时设置availableSlots

于 2013-10-01T08:38:49.097 回答