0

**** Чтобы ограничить поток: ****Я работаю над выполнением очереди заданий. Использование TPL для одного и того же. Попытка ограничить количество заданий за раз с помощью ThreadPool.SetMaxThreads. не повезло

int workerThreads, completionPortThreads; 
ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads); 
workerThreads = 2; 

ThreadPool.SetMaxThreads(workerThreads, completionPortThreads); 

Для выполнения задания я попытался 2 варианта Вариант 1.

ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc),task); 

Вариант 2:

Task runner = new Task(() => taskProcessor.ImportIntoArt(task),TaskCreationOptions.LongRunning|TaskCreationOptions.PreferFairness); 
runner.Start(); 

Я ожидаю, что этот код должен забрать первые два задания для обработки, а третий должен войти в очередь. Как и ожидалось, начнутся первые две вакансии, однако третий будет также выбран для обработки.

Любая помощь очень ценится.

+3

Сколько у вас процессоров? Как [docs] (https://msdn.microsoft.com/en-us/library/system.threading.threadpool.setmaxthreads (v = vs.110) .aspx) говорят: «Вы не можете установить максимальное количество работников потоки или потоки завершения ввода-вывода на число, меньшее, чем количество процессоров на компьютере ». а также «Кроме того, вы не можете установить максимальное количество рабочих потоков или потоков завершения ввода-вывода на число, меньшее, чем соответствующее минимальное количество рабочих потоков или потоков завершения ввода-вывода. Чтобы определить минимальный размер пула потоков, вызовите GetMinThreads ". – stuartd

+0

@stuartd, предполагая, что ваше предположение верно относительно количества процессоров, этот комментарий заслуживает ответа. Я бы поднял его. – adv12

+0

есть ли другой способ сделать это с помощью TPL? – Channa

ответ

0

Используйте QueuedTaskScheduler из this package в сочетании с Task.Factory.StartNew методом:

var scheduler = new QueuedTaskScheduler(TaskScheduler.Default, 2); 

var jobAction = new Action<string>(
    jobName => 
    { 
     Console.WriteLine("I am job " + jobName + " and I start at " + DateTime.Now.ToLongTimeString()); 
     Thread.Sleep(10000); 
     Console.WriteLine("I am job " + jobName + " and I finish at " + DateTime.Now.ToLongTimeString()); 
    }); 

var jobs = Enumerable 
    .Range(1, 6) 
    .Select(num => Task.Factory.StartNew(
     () => jobAction("Job" + num), 
     CancellationToken.None, 
     TaskCreationOptions.LongRunning, 
     scheduler)) 
    .ToList(); 

Task.WhenAll(jobs).Wait(); 
0

Я знаю, что вы хотите, чтобы решить эту задачу с помощью TPL, но @stuartd сделал комментарий, что мы не можем сделать это с ThreadPool , то вы можете достичь этой задачи традиционным путем, создав необходимое количество потоков и бесконечно запускать их и наблюдать коллекцию задачи, которая относится к типу запроса. Если вы хотите выполнить задачу без использования других библиотек, см. Ниже код.

//Declare queue of task. 
     static Queue<int> taskQueue = new Queue<int>(); 
     static readonly object lockObj = new object(); 
     //Get task to perform. 
     static int? GetNextTask() 
     { 
      lock (lockObj) 
      { 
       if (taskQueue.Count > 0) 
        return taskQueue.Dequeue(); 
       else return null; 
      } 
     } 
     //Add task to queue from different thread. 
     static void AddTask(int task) 
     { 
      lock (lockObj) 
      { 
       taskQueue.Enqueue(task); 
      } 
     } 
     static void PerformThreadOperation() 
     { 
      //Run infinite for current thread. 
      while (true) 
      { 
       var task = GetNextTask(); 
       //If there is task then perform some action else make thread sleep for some time you can set event to resume thread. 
       if (task.HasValue) 
       { 
        Console.WriteLine("Task Initiate => {0}", task.Value); 
        Thread.Sleep(4000); 
        Console.WriteLine("Task Complete => {0}", task.Value); 
       } 
       else 
       { 
        Console.WriteLine("Task not found, thread is going to be sleep for some moment."); 
        Console.WriteLine("Thread {0} enter in sleep mode.", Thread.CurrentThread.Name); 
        Thread.Sleep(5000); 
       } 
      } 
     } 
     //Create required thread to process task parallely. 
     static void TestThreadApplication() 
     { 
      Thread thread = new Thread(new ThreadStart(PerformThreadOperation)); 
      Thread thread1 = new Thread(PerformThreadOperation); 
      thread.Start(); 
      thread1.Start(); 
     } 
     static void Main(string[] args) 
     { 
      for (int i = 0; i < 6; i++) 
      { 
       taskQueue.Enqueue(i); 
      } 
      TestThreadApplication(); 
      Thread.Sleep(20000); 

      for (int i = 6; i < 10; i++) 
      { 
       taskQueue.Enqueue(i); 
      } 
      Console.ReadKey(); 
     }