I am trying to build a WCF service that -
- Is single instance
- Allows clients to make multiple request to functions (eg. StartJob)
StarJob(request) 'queues' the request to the TaskFactory (one instance) running on Concurrent task schedule (implemented as per example
As tasks in the task factory are completed, the response is returned
- While a task is running and more requests come in, they get queued (provide max concurrent number is reached)
Objective is to build a system that accepts requests from clients and queues them for processing.
Currently, my code (shown below), runs all requests simultaneously without taking the max concurrent number of task scheduler into account.
Questions
- What am I missing out?
- Any good example/reference I can look at? (I am sure this is not an uncommon use case)
Code
IService
[ServiceContract]
public interface ISupportService
{
[OperationContract]
Task<TaskResponse> StartTask(TaskRequest taskRequest);
}
Service
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class SupportService : ISupportService
{
private static TaskRequestHandler taskRequestHandler;
public SupportService()
{
taskRequestHandler = TaskRequestHandler.GetInstance();
}
public Task<TaskResponse> StartTask(TaskRequest taskRequest)
{
var tcs = new TaskCompletionSource<TaskResponse>();
if (!IsTaskRequestValid(taskRequest))
tcs.SetResult(new TaskResponse()});
taskRequestHandler.StartTaskAsync(taskRequest, lockHandler).ContinueWith(task => { tcs.SetResult(task.Result); });
return tcs.Task;
}
}
TaskRequestHandler
public class TaskRequestHandler
{
private ConcurrentTaskScheduler taskScheduler;
private TaskFactory taskFactory;
private TaskRequestHandler()
{
taskScheduler = new ConcurrentTaskScheduler(2);
taskFactory = new TaskFactory(taskScheduler);
}
private Task<TaskResponse> StartTaskAsync (TaskRequest request, LockHandler lockHandler)
{
var tcs = new TaskCompletionSource<TaskResponse>();
taskFactory.StartNew(() =>
{
//Some task with tcs.SetResults()
});
return tcs.Task;
}
}