2010-05-05 1 views
12

J'écris une application fortement asynchrone.Appels de méthode de file d'attente - aucune idée comment?

Je suis à la recherche d'un moyen de mettre en file d'attente des appels de méthode, similaire à ce que fait BeginInvoke/EndInvoke .... mais sur ma propre file d'attente. La reaqson est que j'ai mon propre système optimisé de mise en file d'attente de messages en utilisant un pool de threads mais en même temps je m'assure que chaque composant est un thread unique dans les requêtes (un thread traite uniquement les messages pour un composant).

J'ai beaucoup de messages qui vont et viennent. Pour un usage limité, j'aimerais vraiment pouvoir mettre en file d'attente un appel avec des paramètres, au lieu de devoir définir mon propre paramètre, la méthode d'emballage/déballage juste pour faire beaucoup d'appels admnistratifs. Je ne veux pas toujours contourner la file d'attente, et je ne veux surtout pas que le service d'envoi attende que l'autre service réponde.

Quelqu'un connaît un moyen d'intercepter un appel de méthode? Un moyen d'utiliser TransparentProxy/Virtual Proxy pour cela? ;) ServicedComponent? Je voudrais que ce soit aussi peu de frais généraux que possible;)

Répondre

13

Que diriez-vous d'utiliser lambdas?

Je veux dire, pourquoi ne pas créer une file d'attente, et de les traiter de la même manière comme

while (!queue.Empty) 
{ 
    Action action = queue.Pop(); 
    action(); // this calls your action 
} 

Vous pouvez ajouter des actions très simplement:

Queue.Add(()=>{ /* any code you wish here */}) 

Ceci est juste une astuce, je Je ne suis pas sûr s'il y a une classe de file d'attente, mais il devrait être assez simple d'en créer un (et threadsafe!) par vous-même.

La solution de contournement pourrait (et devrait) être beaucoup plus sage, mais le point principal est là. Ecrivez-moi si vous voulez consulter.

Pz, le développeur TaskConnect

+0

faire la queue tghe est pas le problème;) je que l'on déjà, et beaucoup de messages qui transportent les mises à jour de données. Mon problème sont les appels de fonction seulement. La file d'attente utilise ensuite un ThreadPool pour obtenir un thread de travail qui traite son contenu;) J'ai beaucoup de choses de mise à jour de données croisées là-bas - maintenant je cherche un moyen de mettre en file d'attente les appels de méthode. Un type de message qui n'a pas de "données" mais un appel de fonction avec tous les paramètres, donc je peux basicall appeler des méthodes sur le service cible. Cela réduirait de manière significative le nombre de messages différents dont j'ai besoin ... – TomTom

+0

et je n'aurais pas à trouver une grosse instruction switch juste pour appeler différentes méthodes. – TomTom

+0

Puisque vous cherchez à faire la queue dans les appels de méthode en cours, passer lambdas semble être exactement ce que vous cherchez ... –

1

Le DynamicProxy qui fait partie du projet Castle permet l'interception membre d'objet sans une partie de la douleur Marshalling typique

http://www.castleproject.org/projects/dynamicproxy/

Vous pouvez l'utiliser pour intercepter vos méthodes appelle et ensuite faire avec eux ce que vous voulez.

2

Créer une file d'attente de

Queue<MethodInvoker> EventCall = new Queue<MethodInvoker>(); 

plus tard ajouter des éléments de MethodInvoker à votre file d'attente

EventCall.Enqueue(ClearAllVals); 
EventCall.Enqueue(saystuff); 
EventCall.Enqueue(testFunc); 

Ensuite, appelez vos fonctions une à la fois:

MethodInvoker bb = EventCall.Dequeue(); 
bb(); 
bb = EventCall.Dequeue(); 
bb(); 
bb = EventCall.Dequeue(); 
bb(); 

appeler tous vos fonctionne d'une manière sûre (ceci les enlèvera également tous de la file d'attente laissant la file vide et toute la fonction s appelé)

public bool InvokeAll(){ 
    MethodInvoker bb = null; // this will hold the function prior to use 
    for(int i = 0; i<EventCall.count; i++){ 

     bb = EventCall.Dequeue(); //pull a method off of the queue 
     bb(); //call the method you pulled off of the queue 

    } 
} 

les appeler tout simplement utiliser InvokeAll(); ou de les appeler une fois chaque fois que vous voulez:

public bool NextEvent(){ 
    MethodInvoker bb = null; // this will hold the function prior to use 
    if(EventCall.count > 0){ 

     bb = EventCall.Dequeue(); //pull a method off of the queue 
     bb(); //call the method you pulled off of the queue 

     } else { 
     MessageBox.Show("there was no event to call"); // this is optional, point being you should be handeling the fact that there is no events left in some way. 
     } 
} 
Questions connexes