2009-04-10 2 views
23

Passing zwei Parameter zu einem neuen Thread auf dem Threadpool kann manchmal kompliziert sein, aber es scheint, dass mit Lambda-Ausdrücke und anonymen Methoden, kann ich dies tun:ThreadPool.QueueUserWorkItem mit einem Lambda-Ausdruck und anonymer Methode

public class TestClass 
{ 
    public void DoWork(string s1, string s2) 
    { 
     Console.WriteLine(s1); 
     Console.WriteLine(s2); 
    } 
} 

try 
{ 
    TestClass test = new TestClass(); 
    string s1 = "Hello"; 
    string s2 = "World"; 
    ThreadPool.QueueUserWorkItem(
     o => test.DoWork(s1, s2) 
     ); 
} 
catch (Exception ex) 
{ 
    //exception logic 
} 

Nun, ich habe dieses Beispiel sicherlich vereinfacht, aber diese Punkte sind der Schlüssel:

  • Die String-Objekte THREAD
  • Die s1 und s2 Variablen sind unveränderlich und daher übergeben wird erklärt w ith im Rahmen des try-Blocks, den ich sofort nach dem Einreihen der Arbeit in den Thread-Pool verlasse, so dass die Variablen s1 und s2 danach nie geändert werden.

Ist da etwas nicht in Ordnung?

Die Alternative besteht darin, eine neue Klasse zu erstellen, die einen unveränderlichen Typ mit drei Mitgliedern implementiert: test, s1 und s2. Das scheint nur eine zusätzliche Arbeit ohne Nutzen zu sein.

+1

Warum schreibst du nicht einfach "o => test.DoWork (s1, s2)" anstelle der ausführlicheren Definition? –

+0

@Mehrdad: Weil ich Lambda-Ausdrücke wirklich neu bin. ;) - Vielen Dank! –

+0

@Mehrdad: Ich habe es in der Frage geändert. –

Antwort

16

Es ist nichts falsch daran. Der Compiler erledigt im Wesentlichen automatisch das, was Sie als Ihre Alternative beschrieben haben. Es erstellt eine Klasse für die erfassten Variablen (test, s1 und s2) und übergibt eine Delegat-Instanz an das Lambda, das in eine Methode für die anonyme Klasse umgewandelt wird. Mit anderen Worten, wenn Sie mit Ihrer Alternative fortfahren würden, würden Sie mit etwas sehr Ähnlichem enden, was der Compiler gerade für Sie generiert hat.

2

Es ist eine nette Art, es zu tun. Ich sehe keine Nachteile bei der Verwendung von Lambdas. Es ist einfach und sauber.

4

Für dieses spezielle Beispiel, nein ist hier nichts falsch. Der Status, den Sie an den anderen Thread übergeben haben, ist vollständig enthalten und keiner der Typen enthält Probleme mit der Thread-Affinität.

+0

Was ist dann mit dem allgemeinen Muster? Wie würde man wissen, ob ein Typ Thread-Affinitätsprobleme hat? –

+0

Im Grunde fragen Sie, ob eine Klasse threadsafe ist oder nicht. In meiner speziellen Implementierung (in den meisten Fällen) verwende ich tief unveränderliche Objekte, um sie threadsicher zu machen. Andere Möglichkeiten, um Objekte threadsicher zu machen, sind Sperren usw. –

+0

@Joel Wenn ein Typ Probleme mit der Thread-Affinität hat, sind Sie Toast. Sie können nichts damit auf einem separaten Thread tun. Das allgemeine Muster ist jedoch Sound (ich verwende es oft) – JaredPar

2

Was Sie betrachten, wird als eine Schließung bezeichnet. Als chuckj states generiert der Compiler eine Klasse zum Zeitpunkt der Kompilierung, die den Elementen entspricht, auf die außerhalb des Abschlusses zugegriffen wird.

Die einzige Sache, um die Sie sich sorgen müssen, ist, wenn Sie ref oder out Parameter haben. Während Strings unveränderlich sind, sind die Referenzen auf sie (oder eine Variable) NICHT.

1

Ein mögliches Problem mit dem Muster ist, dass es sehr es in etwas mehr generisch, aber weniger sicher so zu erweitern verlockend (Kratzern Code- es funktioniert nicht erwarten):

public static void QueueTwoParameterWorkItem<T1, T2>(T1 value1, T2 value2, workDelegate<T1,T2> work) 
{ 
    try 
    { 
     T1 param1 = value1; 
     T2 param2 = value2; 
     ThreadPool.QueueUserWorkItem(
      (o) => 
      { 
       work(param1, param2); 
      }); 
    } 
    catch (Exception ex) 
    { 
     //exception logic 
    } 
} 
+0

In meinem Fall habe ich eine zutiefst unveränderliche Basisklasse, die ich verwenden könnte, um T1 und T2 zu nageln ... also könntest du dies in meinem speziellen Fall zum Laufen bringen. Wenn Sie die Threading-Probleme nicht verstehen, kommt die Verwendung des Threadpools sowieso nicht in Frage. –

+0

Einverstanden: Ihr spezifischer Fall ist in Ordnung. Wenn Sie es als generisches Muster implementieren, gibt es Bedenken. –

Verwandte Themen