2015-06-19 111 views
3

裏面我想知道如何,甚至如果在我的情況與物體任務中運行的通信所需。溝通與目標任務

我有一個過程的集合,這是執行需要長時間運行的監控和計算一般對象:因爲它們是基於它們實現的方法,以「doSomeWork」的共同界面上

private IEnumerable<IService> _services; 

。因此,爲了爭論,sakes讓我們稱之爲DoWork方法。

我希望這些方法都在一個單獨的任務空間中運行,而不是按順序阻塞,因此,我在類似的水平範圍內旋轉了一個任務列表運行程序的這一部分。

private List<Task> ProcessTask = new List<Task>(); 
private CancellationTokenSource tokenSource = new CancellationTokenSource(); 
private CancellationToken token; 

private void startAll() 
{ 
    token = tokenSource.Token; 
    ProcessTask = _services.Select(service => Task.Factory.StartNew(
    () => StartService(service), 
    token, 
    TaskCreationOptions.LongRunning, 
    TaskScheduler.Current)).ToList(); 
} 

的startservice方法基本上開始於個別項目的監測工作:

private void StartService(IService plugin) 
{ 
    ... 
    ... 
    plugin.DoWork(); 
    ... 
    ... 
} 

的服務也有一個方法來「停止」和「繼續」,這導致了我的問題。在使用任務的核心,我最好試圖找到一種方式來影響使用事件或委託來執行任務的服務,並暫停/停止任務,或僅從外部_services集合中調用這些方法?

例如爲:

_services.ForEach(item => item.Stop()); 

如果是前者那麼我該如何引發一個事件從側面出裏面的任務,或者我應該監控外部標誌?

+0

您必須爲任務和外界知道的每項任務引入一種背景。該任務必須定期檢查標誌是否具有由外部設置的某些特殊價值並對其採取行動。 –

+0

感謝@Mario,所以我可以添加類似ConcurrentQueue或阻塞集合到類級別來發送任務收集的消息? – DubMan

+0

是的,只保留併發性和鎖定 - 還記得ConcurrentQueue會比整數標誌慢 - 您可以使用Increment.xxxx操作來設置和檢查它。但這取決於你的表現如何至關重要 - 如果不是,只要保持簡單即可。 –

回答

2

可以使用CancellationToken作爲一次性事件:

token.Register(() => item.Stop()) 

我們希望,這將與您的特殊「服務」 API的工作。請注意,令牌可以在服務啓動之前以及完成之後啓動。

+0

謝謝@usr,會嘗試看看是否有幫助。 – DubMan

+0

似乎工作。至少對於一種方法。但是,我需要一個新的令牌爲每個項目的清單? – DubMan

+0

您需要執行一個不同的取消事件的令牌。 – usr

0

完整的解決方案的代碼是: 我的新的容器類

internal class ServiceContainer 
{ 
    /// <summary> 
    /// Process service which runs the monitor 
    /// </summary> 
    public IService ServiceProcess { get; private set; } 

    /// <summary> 
    /// Cancellation token used to cancel the operation 
    /// </summary> 
    public CancellationTokenSource CancelTokenSource { get; private set; } 

    internal ProcessContainer(IService plugin) 
    { 
     this.PluginProcess = plugin; 
     CancelTokenSource = new CancellationTokenSource(); 
    } 
} 

然後創建服務包裝清單:

serviceWrapperList = _plugins.Select(service => new ServiceContainer(service)).ToList(); 

然後,我讓我的任務運行和基礎服務集:

ProcessTaskList = serviceWrapperList.Select(serviceSet => Task.Factory.StartNew(
      () => 
      { 
       IService service = serviceSet.ServiceProcess; 
       CancellationToken token = serviceSet.CancelTokenSource.Token; 
       StartService(service); 
       token.Register(() => StopPlugin(service)); 
      }, 
      serviceSet.CancelTokenSource.Token, 
      TaskCreationOptions.LongRunning, 
      TaskScheduler.Current)).ToList(); 

最後,我有我停止所有方法。

protected void StopAllServices() 
    { 
     ProcessTaskList.ForEach(f => f.CancelTokenSource.Cancel()); 
    }