2016-08-04 1 views
1

Je suis en train de construire un service WCF qui -.instance unique service WCF avec des tâches concurrentes (qui peuvent être limités)

  1. est-seule instance
  2. Permet aux clients de faire une demande multiple aux fonctions (par exemple StartJob)
  3. StarJob (demande) « files d'attente » la demande au TaskFactory (une instance) en cours d'exécution dans les délais prévus des tâches simultanées (mis en œuvre conformément example

  4. comme tâches dans l'usine de tâches sont com iné, la réponse est renvoyée

  5. Alors qu'une tâche est en cours d'exécution et plus de demandes arrivent, ils sont mis en attente (fournir nombre simultané maximum est atteint)

L'objectif est de construire un système qui accepte les demandes des clients et les met en file d'attente pour le traitement.

Actuellement, mon code (illustré ci-dessous), exécute toutes les demandes simultanément sans prendre en compte le nombre maximal simultané de planificateur de tâches.

Questions

  1. Qu'est-ce que je manquais?
  2. Tout bon exemple/référence que je peux regarder? (Je suis sûr que ce n'est pas un cas d'utilisation rare)

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; 
    } 
} 
+0

Cette question peut vous aider à faire la queue et de la concurrence: http://stackoverflow.com/questions/7122608/ wcf-concurrencymode-single-et-instancecontextmode-percall/7149683 # 7149683 –

Répondre

0

Aaaah! Un gros manque de ma part. L'action exécutée en taskFactory se terminait avant que je m'y attendais. A ce titre, toutes les tâches sont apparues pour fonctionner en parallèle.

J'ai mis à jour le code d'action pour surveiller correctement la fin de l'action et déclencher des rappels corrects, le code ci-dessus a bien fonctionné.

Cependant, fait un changement mineur -

  • Il n'y a pas besoin de StartTask(TaskRequest taskRequest) pour retourner un Task. Au contraire, juste retourner le TaskResponse suffit (comme WCF prend en charge la fonctionnalité Async et Sync de chaque OperationContract)