2017-08-11 73 views
0

我正在嘗試創建單個消費者和多個生產者模式。生產者將向BlockingCollection添加任務,而消費者將運行這些任務。我想知道是否有辦法知道消費者產生的所有任務的執行是否完成。任何方式知道什麼時候BlockingCollection中的所有任務完成執行?(任務將在開始時被刪除,但如果exec想完成,我想知道)

public TaskQueue(IProducerConsumerCollection<Task> workTaskCollection) 
     { 
      _workTaskQueue = new BlockingCollection<Task>(workTaskCollection); 
     } 

     public void EnqueueTask(Action action, CancellationToken cancelToken = default(CancellationToken)) 
     { 
      var task = new Task(action, cancelToken); 
      if (_workTaskQueue.TryAdd(task)) 
      { 
       TaskHandler?.Invoke 
        (new TaskProcessingArguments 
        { 
         ISTaskAdded = true, 
         Message = "Task Added to Queue", 
         PendingTaskCount = _workTaskQueue.Count, 
        }); 
      } 
      else 
      { 
       TaskHandler?.Invoke 
        (new TaskProcessingArguments 
        { 
         ISTaskAdded = false, 
         Message = "Timedout while adding Task to Queue", 
         PendingTaskCount = _workTaskQueue.Count, 
        }); 
      } 
     } 


     public void DequeueTask() 
     { 
      foreach (var task in _workTaskQueue.GetConsumingEnumerable()) 
       try 
       { 
        if (!(task.IsCanceled) && task.Status == TaskStatus.Created) 
        { 
         task.Start(); 
        } 
       } 
       catch (Exception ex) 
       { 

       } 
     } 
     public static void Run() 
       { 
        Task.Factory.StartNew(() => 
        { 
          taskQueue.DequeueTask(); 

        }, TaskCreationOptions.LongRunning); 
       } 
+0

請勿使用'Task'構造函數。並'避免'StartNew'方法。 – VMAtm

回答

0

而不是提供「EnqueueTask」與行動(和方法創建的任務),你可以在生產者本身創建任務,並通過這種對「EnqueueTask」方法。 通過這種方式,每個生產者可以維護已提交的任務列表,間歇性地查詢每個生產者的狀態並刪除已完成的任務。

這增加了一個優點,即生產者可以取消它已經提交的任務(甚至在它們啓動之前)或檢測由於異常而中止的任務。

相關問題