2013-07-29 9 views
13

in meiner csharp Anwendung i bestimmte Ereignisse haben, die Funktionen auslösen sollte auf einem bestimmten Thread aufgerufen werden, die durch einige Code Looping.Sammlung von Funktionen

jetzt, statt alle diese Daten von Hand und mit einem großen Switch-Fall zu speichern, fragte ich mich, ob es möglich ist, diese Funktionen und ihre Parameter in einer Liste zu speichern, die dann von dem anderen Thread verarbeitet wird?

Pseudocode:

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

anderen thread:

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

Sie können [Delegaten] (http://msdn.microsoft.com/en-us/library/ms173172.aspx) verwenden, die C# 's Version von Funktionszeigern sind. –

+0

Unabhängig davon, welche Methode Sie verwenden, stellen Sie sicher, dass Sie eine thread-sichere "Liste" verwenden, um sicherzustellen, dass keine Synchronisierungsprobleme zwischen den Threads auftreten. –

Antwort

18

Ja, können Sie dies tun, indem Sie einen List<Action> oder eine Queue<Action> verwendet, die meiner Meinung nach etwas besser passt. Action ist ein Typ für einen no-Parameter ungültig Delegaten:

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()(); 
} 

Wenn Sie Parameter benötigen, verwenden Action<T> für einen, Action<T, T> für zwei und so weiter. Verwenden Sie für einen Rückgabewert Func anstelle von Action (oder Func<T> usw.).

Vielleicht ein Ereignis würde auch Ihnen helfen. Ereignisse sind C# 's Sprachfeature, um das Beobachtermuster zu verwenden.

// 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); 
} 

Ein Ereignis ist ein Multicastdelegat, die ein Delegierter zu einer Liste der Funktionen ist. Sie können nicht das Einfädeln obwohl für jeden Handler steuern: Im Gegensatz zum Queue<Action> oben, wo Sie Threads beginnen oder wieder verwenden können, ein Multicast-Delegate als ein Anruf ausgesetzt von außen, so dass Sie für alle Beschwörungen nur einen Thread verwenden.

+4

@clamp Man beachte, dass [ 'Action'] (http://msdn.microsoft.com/en-us/library/system.action.aspx) ist nur ein vordefinierter Typ für eine Funktion ohne Parameter und keinen Rückgabewert. Wenn Sie wollen, dass die Funktionen Parameter übernehmen oder etwas zurückgeben, können Sie das trotzdem tun, die Typ-Signatur wird nur etwas länger sein. –

1

Ich glaube, Sie Ereignisse auf diese Weise umsetzen. Sie brauchen keinen großen Schalter, Sie benötigen mehrere Ereignisse und lösen dann das richtige Ereignis zur richtigen Zeit aus und registrieren es mit der richtigen Methode.

Sie können eine Liste der Delegierten tun, aber es wird immer komplizierter starten, wenn Sie andere Funktion mit unterschiedlichem Satz von Parametern wollen.