2010-05-05 11 views
12

Scrivo un'applicazione pesantemente asincrona.Chiamate di metodi di accodamento - qualche idea di come?

Sto cercando un modo per accodare le chiamate di metodo, simile a ciò che BeginInvoke/EndInvoke fa .... ma sulla mia coda PROPRIO. Il reaqson è che sto avendo il mio sistema di accodamento dei messaggi ottimizzato usando un threadpool ma allo stesso tempo assicurandomi che ogni componente sia a thread singolo nelle richieste (cioè un thread gestisce solo i messaggi per un componente).

Ho molti messaggi che vanno avanti e indietro. Per un uso limitato, mi piacerebbe molto essere in grado di accodare una chiamata di messaggio con parametri, invece di dover definire il mio parametro, metodo wrapping/unwrapping solo per fare molte chiamate amministrative. Inoltre, non sempre voglio ignorare la coda e sicuramente non voglio che il servizio di invio attenda che l'altro servizio risponda.

Qualcuno conosce un modo per intercettare una chiamata di metodo? Un modo per utilizzare TransparentProxy/Virtual Proxy per questo? ;) ServicedComponent? Vorrei che questo fosse il più piccolo possibile possibile;)

risposta

13

Che ne dici di usare lambda?

Voglio dire, perché non si fa a creare un po 'di coda, ed elaborarli in modo simile

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

È possibile aggiungere le azioni in modo molto semplice:

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

Questo è solo un suggerimento, ho Non sono sicuro che ci sia qualche classe di coda, ma dovrebbe essere abbastanza semplice crearne una (e il thread sicuro!) da solo.

La soluzione alternativa potrebbe (e dovrebbe) essere molto più saggia, ma il punto principale è lì. Scrivimi se vuoi consultarmi.

Pz, lo sviluppatore TaskConnect

+0

tghe messa in coda non è il problema;) ho che uno già, e un molti messaggi che trasportano gli aggiornamenti dei dati. Il mio problema sono solo le chiamate di funzione. La coda quindi utilizza un ThreadPool per ottenere un thread di lavoro che elabora il suo contenuto;) Ho un sacco di processi di aggiornamento dei dati cross-process lì - ora cerco un modo per effettuare chiamate di metodo in coda (in elaborazione). Un tipo di messaggio che non ha "dati" ma una chiamata di funzione con tutti i parametri, quindi posso utilizzare tutti i metodi di chiamata sul servizio di destinazione. Ciò ridurrebbe in modo significativo il numero di messaggi diversi che mi servono ... – TomTom

+0

e non avrei dovuto elaborare una dichiarazione dell'interfaccia hugh solo per chiamare metodi diversi. – TomTom

+0

Dato che stai cercando di fare la fila per le chiamate al metodo in-process, passare lambdas sembra essere esattamente quello che stai cercando ... –

1

Il DynamicProxy che fa parte del progetto di Castello consente membro oggetto di intercettazione, senza alcuni dei tipici dolore Marshalling

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

È possibile utilizzare questo per intercettare i vostri metodi chiama e poi fai con loro quello che vuoi.

2

Creare una coda di di MethodInvoker

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

Successivamente aggiungere elementi alla coda

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

Quindi chiamare le funzioni una alla volta:

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

per chiamare tutti i tuoi funziona in modo sicuro (questo rimuoverà anche tutti dalla coda lasciando la coda vuota e tutte le funzioni s chiamato)

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 

    } 
} 

a chiamarli tutti basta usare InvokeAll(); o chiamare loro una volta ogni volta che si desidera:

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. 
     } 
} 
Problemi correlati