Communication with an object within a task
I want to know how or even if it is necessary in my case to communicate with an object launched inside a task.
I have a set of processes that are generic objects that do some lengthy monitoring and computation:
private IEnumerable<IService> _services;
Since they are based on a common interface, they implement the "doSomeWork" method. Therefore, you can call this DoWork method for arguments.
I want all of these methods to run in a separate task space rather than sequentially, so I run the task list at the same visibility level to run this part of the program.
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();
}
The startervice method basically starts monitoring and working on a single item:
private void StartService(IService plugin)
{
...
...
plugin.DoWork();
...
...
}
Services also have a "stop" and "continue" method, which leads to my question. At the core of using tasks, I would try to find a way to affect service with a task using an event or delegate, pause / stop the task, or just call these methods on an element from the external _services collection?
eg:.
_services.ForEach(item => item.Stop());
If this is the first one, then how should I raise the event inside the task from the outside, or should I control the external flag?
source to share
Complete solution code: My new container class
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();
}
}
Then create a list of service wrappers:
serviceWrapperList = _plugins.Select(service => new ServiceContainer(service)).ToList();
Then I start my task and set of services:
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();
Finally, I have my stop method.
protected void StopAllServices()
{
ProcessTaskList.ForEach(f => f.CancelTokenSource.Cancel());
}
source to share