2015-06-19 74 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()); 
    }