Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
任务计数器C#,联锁_C#_Task - Fatal编程技术网

任务计数器C#,联锁

任务计数器C#,联锁,c#,task,C#,Task,我希望并行运行任务,在给定时间运行的实例不超过10个 这是我目前掌握的代码: private void Listen() { while (true) { var context = listener.GetContext(); var task = Task.Run(() => HandleContextAsync(context)); Interlocked.Increment(ref countTask);

我希望并行运行任务,在给定时间运行的实例不超过10个

这是我目前掌握的代码:

private void Listen()
{
    while (true)
    {
        var context = listener.GetContext();
        var task = Task.Run(() => HandleContextAsync(context));
        Interlocked.Increment(ref countTask);
        if (countTask > 10)
        {
            //I save tasks in the collection
        }
        else
        {
            task.ContinueWith(delegate { Interlocked.Decrement(ref countTask); }); //I accomplish the task and reduce the counter
        }
    }
}

我建议您使用并行循环;例如:

Parallel.For(1, 10, a =>
{
      var context = listener.GetContext();
      ...
});

这将启动定义数量的任务,而无需您自己管理流程。

如果您希望连续并行执行代码,一次最多10个实例,这可能值得考虑:

private void Listen()
{
    var options = new ParallelOptions() { MaxDegreeOfParallelism = 10 };
    Parallel.For(1, long.MaxValue - 1, options, (i) =>
    {
        var context = listener.GetContext();
        HandleContextAsync(context);
    });
}

基本上,它将连续运行代码(大致是
long.MaxValue
次)
MaxDegreeOfParallelism
确保它一次只运行10个代码“实例”。

我假设
GetContext
的结果不是由您创建的,因此,如果您不知道要运行多少次或者没有立即处理所有上下文,那么使用
并行可能没有用

因此,解决这个问题的最佳方法可能是实现您自己的
TaskScheduler
。通过这种方式,您可以添加更多的任务,以便在具有固定并发级别的情况下按需解决

根据网站上的例子,你已经可以做到这一点

我制作了一个示例程序,对网站上的
limitedconcurrentyleveltaskscheduler
进行了一些更改

使用系统;
使用System.Collections.Generic;
使用系统线程;
使用System.Threading.Tasks;
名称空间并行
{
班级计划
{
私有静态随机兰德=新随机();
静态void Main(字符串[]参数)
{
var ts=新的LimitedConcurrencyLevel任务调度器(10);
var taskFactory=新taskFactory(ts);
while(true)
{
var-context=GetContext(ts);
if(context.Equals(“Q”,StringComparison.OrdinalIgnoreCase))
打破
StartNew(()=>HandleContextAsync(上下文));
}
控制台。WriteLine(“等待…”);
同时(ts.CountRunning!=0)
{
WriteLine(“正在运行{0}x任务,其中{1}x已排队。”,ts.CountRunning,ts.CountQueued);
螺纹屈服强度();
睡眠(100);
}
}
私有静态void HandleContextAsync(字符串上下文)
{
//延迟1-10秒,使示例更易于理解
Thread.Sleep(Rand.Next(100010000));
WriteLine(“上下文:{0},来自线程:{1}”,上下文,线程.CurrentThread.ManagedThreadId);
}
私有静态字符串GetContext(LimitedConcurrencyLevel任务调度器ts)
{
WriteLine(“正在运行{0}x任务,其中{1}x已排队。”,ts.CountRunning,ts.CountQueued);
返回控制台ReadLine();
}
}
//提供一个任务计划程序,确保在运行时达到最大并发级别
//在线程池的顶部运行。
公共类LimitedConcurrentYlevelTaskScheduler:TaskScheduler
{
//指示当前线程是否正在处理工作项。
[线程静态]
私有静态bool\u currentThreadIsProcessingItems;
//要执行的任务列表
私有只读LinkedList _tasks=new LinkedList();//受锁保护(_tasks)
public int CountRunning=>\u nowlunning;
公共整数排队
{
得到
{
锁定(_任务)
{
return_tasks.Count;
}
}
}
//此计划程序允许的最大并发级别。
私有只读int_maxDegreeOfParallelism;
//指示计划程序当前是否正在处理工作项。
私有volatile int_delegatesquedorrunning=0;
私有volatile int正在运行;
//创建具有指定并行度的新实例。
public limitedconcurrencedyleveltaskscheduler(int-maxDegreeOfParallelism)
{
if(最大平行度<1)
抛出新ArgumentOutOfRangeException(“maxDegreeOfParallelism”);
_maxDegreeOfParallelism=maxDegreeOfParallelism;
}
//将任务排入调度程序队列。
受保护的密封覆盖无效队列任务(任务任务)
{
//将任务添加到要处理的任务列表中。如果没有足够的任务
//当前排队或正在运行以处理任务的代理计划另一个任务。
锁定(_任务)
{
_tasks.AddLast(任务);
如果(_delegatesquedorrunning<_maxDegreeOfParallelism)
{
联锁。增量(参考delegatesquedorunning);
NotifyThreadPoolOfPendingWork();
}
}
}
//通知线程池此计划程序有要执行的工作。
私有void NotifyThreadPoolOfPendingWork()
{
ThreadPool.UnsafeQueueUserWorkItem(=>
{
//请注意,当前线程现在正在处理工作项。
//这是将任务内联到此线程中所必需的。
_currentThreadIsProcessingItems=true;
尝试
{
//处理队列中的所有可用项。
while(true)
{
任务项;
锁定(_任务)
{
//当没有更多要处理的项目时,
//请注意,我们已完成处理,请退出。
如果(_tasks.Count==0)
{
联锁减量(参考DelegateSqueuedoRunning);
打破
}
//得到