2013-07-29 12 views
13

nella mia applicazione csharp ho determinati eventi che dovrebbero far sì che le funzioni vengano richiamate su un thread specifico, che sta eseguendo il ciclo di codice.Raccolta di funzioni

ora, invece di archiviare tutti questi dati a mano e avendo un grande switch-case mi chiedevo se è possibile memorizzare queste funzioni e i loro parametri in una lista che viene poi elaborata dall'altro thread?

pseudo codice:

var func = pointer2somefunction(13, "abc"); 
list.add(func); 

altro thread:

while (list.Count > 0) 
{ 
    var func = list.Remove(0); 
    func.Invoke(); 
} 
+6

È possibile utilizzare [delegati] (http://msdn.microsoft.com/en-us/library/ms173172.aspx), che sono la versione di puntatori di funzione di C#. –

+0

Qualunque sia il metodo che usi, assicurati di utilizzare un 'Elenco' sicuro per i thread per assicurarti che non si verifichino problemi di sincronizzazione tra i thread. –

risposta

18

Sì, è possibile farlo utilizzando un List<Action> o un Queue<Action> che si adatta un po 'meglio a mio parere. Action è un tipo per un no-parametro vuoto delegato:

var functions = new Queue<Action>(); 

functions.Enqueue(() => Console.WriteLine("Foo")); 
functions.Enqueue(() => Console.WriteLine("Bar")); 

while (functions.Any()) 
{ 
    // note the double parenthesis here: one for Dequeue 
    // and one for your dequeued function 
    functions.Dequeue()(); 
} 

Se avete bisogno di parametri, utilizzare Action<T> per uno, Action<T, T> per due e così via. Per un valore restituito, utilizzare Func anziché Action (o Func<T> ecc.).

Forse un evento ti può aiutare. Gli eventi sono funzionalità di linguaggio C# per utilizzare il modello di osservatore .

// events are usually on the instance rather than static 
private static event EventHandler MyEvent; 

static void Main(string[] args) 
{ 
    MyEvent += (s, e) => Console.WriteLine("FooEvent"); 
    MyEvent += (s, e) => Console.WriteLine("BarEvent"); 
    MyEvent(null, EventArgs.Empty); 
} 

un evento è un delegato multicast , che è un delegato ad un elenco di funzioni. Tuttavia, non è possibile controllare il threading per ogni gestore: a differenza dello Queue<Action> in cui è possibile avviare o riutilizzare i thread, un delegato multicast viene esposto come dall'esterno una chiamata, consentendo di utilizzare solo un thread per tutte le chiamate.

+4

@clamp Si noti che ['Azione'] (http://msdn.microsoft.com/en-us/library/system.action.aspx) è solo un tipo predefinito per una funzione senza parametri e senza valore di ritorno. Se vuoi che le funzioni prendano parametri o restituiscano qualcosa, puoi comunque farlo, la firma del tipo sarà solo un po 'più lunga. –

1

Penso che tu stia implementando gli eventi in questo modo. Non hai bisogno di un grande caso di switch, hai bisogno di diversi eventi, quindi attiva l'evento giusto nel momento giusto e registralo con il metodo giusto.

È possibile eseguire un elenco di delegati, ma inizierà a complicarsi quando si desidera una funzione diversa con un set di parametri diverso.