Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.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#_Multithreading - Fatal编程技术网

在C#中创建分区线程池最干净的方法是什么?

在C#中创建分区线程池最干净的方法是什么?,c#,multithreading,C#,Multithreading,我想要一个线程池,它允许以这样的方式对工作进行分区或“扣合”,这样任务就可以跨线程分布,但给定id的任务永远不会并行处理 因此,例如,当我调度任务时,如果我有5个唯一id和5个线程,我希望id为“1”的任务总是分配给线程1,id为“2”的任务总是分配给线程2,id为“3”的任务总是分配给线程3,等等 如果id多于线程,则每个线程可以分配多个id,例如,如果有10个id和5个线程,则线程1可以分配给id“1”和“5”,线程2可以分配给id“2”和“6”等我发现解决此问题的最干净方法是使用,这是TP

我想要一个线程池,它允许以这样的方式对工作进行分区或“扣合”,这样任务就可以跨线程分布,但给定id的任务永远不会并行处理

因此,例如,当我调度任务时,如果我有5个唯一id和5个线程,我希望id为“1”的任务总是分配给线程1,id为“2”的任务总是分配给线程2,id为“3”的任务总是分配给线程3,等等


如果id多于线程,则每个线程可以分配多个id,例如,如果有10个id和5个线程,则线程1可以分配给id“1”和“5”,线程2可以分配给id“2”和“6”等

我发现解决此问题的最干净方法是使用,这是TPL的一部分,基本上与读写器锁的工作方式类似,它公开了一个ExclusiveScheduler和一个ConcurrentScheduler。ConcurrentScheduler允许多个线程同时执行,ExclusiveScheduler一次只能执行一个线程,当ExclusiveScheduler中有线程执行时,不允许在ConcurrentScheduler上执行线程

通过使用分片算法维护分配给唯一ID的ExclusiveScheduler对象池,可以实现分区调度器

    public class TaskSchedulerPool
    {
        private readonly List<Lazy<TaskScheduler>> _taskSchedulers;

        public TaskSchedulerPool(int maxSize)
        {
            _taskSchedulers = Enumerable.Range(1, maxSize)
                .Select(
                    _ => new Lazy<TaskScheduler>(() => new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler))
                .ToList();
        }

        public TaskScheduler GetTaskScheduler(object o)
        {
            var partition = Math.Abs(o.GetHashCode())%_taskSchedulers.Count;
            return _taskSchedulers[partition].Value;
        }

    }

executive scheduler将确保对于给定的密钥,任务永远不会被并发处理。

我找到的解决此问题的最干净的方法是使用,这是TPL的一部分,基本上与读写器锁的工作方式类似,它公开了一个ExclusiveScheduler和一个ConcurrentScheduler。ConcurrentScheduler允许多个线程同时执行,ExclusiveScheduler一次只能执行一个线程,当ExclusiveScheduler中有线程执行时,不允许在ConcurrentScheduler上执行线程

通过使用分片算法维护分配给唯一ID的ExclusiveScheduler对象池,可以实现分区调度器

    public class TaskSchedulerPool
    {
        private readonly List<Lazy<TaskScheduler>> _taskSchedulers;

        public TaskSchedulerPool(int maxSize)
        {
            _taskSchedulers = Enumerable.Range(1, maxSize)
                .Select(
                    _ => new Lazy<TaskScheduler>(() => new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler))
                .ToList();
        }

        public TaskScheduler GetTaskScheduler(object o)
        {
            var partition = Math.Abs(o.GetHashCode())%_taskSchedulers.Count;
            return _taskSchedulers[partition].Value;
        }

    }

executive scheduler将确保给定密钥的任务永远不会被并发处理。

您可能需要查看SmartThreadPool及其工作项组功能您可能需要查看SmartThreadPool及其工作项组功能