2013-07-02 2 views
19

Gerade jetzt verwende ich folgenden Code zum Hinzufügen von Threads in Warteschlange. Ich mag es nicht. Und meine Kollegen werden das auch nicht, weil sie C# nicht sehr gut kennen. Alles, was ich will, ist natürlich, eine Methode in einem neuen Thread in die Warteschlange zu stellen.C# - ThreadPool QueueUserWorkItem Verwenden?

private static void doStuff(string parameter) 
{ 
    // does stuff 
} 

// call (a) 
ThreadPool.QueueUserWorkItem(a => doStuff("hello world")); 
// call (b) 
ThreadPool.QueueUserWorkItem(delegate { doStuff("hello world"); }); 

So gibt es andere Verwendung Variationen ThreadPool.QueueUserWorkItem?

Am besten wäre ein weiterer 1-Line-Call. Wenn möglich unter Verwendung von Func<> oder Action<>.


EDIT: Got (b) aus den Antworten und Kommentare und ich mag es schon besser.

+2

Was ist falsch mit ThreadPool.QueueUserWorkItem() in Ihrem Szenario? –

+1

könnten Sie "Delegate" Schlüsselwort verwenden. Etwas wie ThreadPool.QueueUserWorkItem (Delegat {doStuff ("");}). Genauso wie die obige Methode, aber wie Sie es wünschen, ist dies nur eine andere Art, es zu tun. –

+1

Warum in der Welt würden Sie denken, Delegate Syntax ist sauberer als Lambdas !? –

Antwort

12

Die Antwort auf Ihre Frage hängt davon ab, wie Sie die Anwendung entwerfen. Bringst du es in ein gemeinsames Projekt? Sie wollen keine einfachen Operationen über Kopf.

Aber Sie könnten einen generischen Aufruf für ThreadPool QueueUserItem erstellen, die params, 1 param, 2 param, etc .. Das ist gut, anstatt eine einfache Zeichenfolge zu senden und eingeschränkt werden.

Diese, wie Sie einen Parameter impl QueueUserItem mit WaitCallback:

ThreadPool.QueueUserWorkItem(
    new WaitCallback(delegate(object state) 
    { YourMethod(Param1, Param2, Param3); }), null); 

genommen von C# Execute Method (with Parameters) with ThreadPool

Und einige Links für Ideen:
http://msdn.microsoft.com/en-us/library/4yd16hza.aspx
Generic ThreadPool in .NET
Difference between delegate.BeginInvoke and using ThreadPool threads in C#

+0

Wäre das auch mit 'Func' oder' Action' möglich oder ohne den zusätzlichen Call Body? – Bitterblue

+0

Es wird möglich sein, wenn Sie das WaitCallback erstellen, senden Sie nicht einfach einen "Delegaten", senden Sie stattdessen Ihren eigenen Delegaten. * aber *, wie erwartest du, das Ergebnis zurück zu bekommen? In der Regel wird beim Senden der Operation an den Worker-Thread kein Ergebnis erwartet, um sicherzustellen, dass der Job erledigt ist. Sie können dies erreichen, indem Sie ein asynchrones Muster implementieren. http://www.c-sharpcorner.com/UploadFile/rmcochran/multithreadasyncwebservice05262007094719AM/multithreadasyncwebservice.aspx – ilansch

13

Ich bin mir nicht ganz sicher, welche Art von Syntax Sie suchen, aber wenn Sie die unbenutzte a in Ihrem Beispiel nicht mögen, warum nicht stattdessen Task verwenden?

Es scheint nicht wirklich viel besser, aber zumindest hat es keine ungenutzte Kennung.

Hinweis: Task.Run() ist .Net 4.5 oder höher. Wenn Sie .Net 4 verwenden, müssen Sie Folgendes tun:

Task.Factory.StartNew(() => doStuff("hello world")); 

was nicht so kurz ist.

Beide oben verwenden den Thread-Pool.

Wenn Sie wirklich vermeiden muss ein Lambda verwenden, können Sie einen anonymen Delegaten verwenden (die bereits erwähnte @nowhewhomustnotbenamed):

Task.Run(delegate { doStuff("Hello, World!"); }); 

Aber was ist der Sinn davon? Es ist viel weniger lesbar!

+0

Eigentlich möchte ich die Lambda-Sache vermeiden. – Bitterblue

+0

@ mini-me Nun habe ich ein Beispiel hinzugefügt, das vermeidet, ein Lambda zu verwenden ... Es ist schlimmer, tho, IMO. –

+9

@ mini-me Lambda-Ausdrücke haben ziemlich viele anonyme Delegierte ersetzt. Sie würden also gut daran tun, sich eher früher als später daran zu gewöhnen. – nashwan

2

Was darüber ?

class Program 
{ 
    static void Main(string[] args) 
    { 
     ThreadPool.QueueUserWorkItem(MyWork, "text"); 
     Console.ReadKey(); 
    } 

    private static void MyWork(object argument) 
    { 
     Console.WriteLine("Argument: " + argument); 
    } 
} 

Oder wenn Sie nicht wollen, eine einfache Art und Weise der Umsetzung Methoden an einem Faden Signatur restriktiv und sein müssen Sie es wie this.For Methoden tun können, die tun und das Rück keinen Wert und haben bis zu 6 Parameter würde es erfordern, dass Sie 12 Überladungen definieren, wenn ich mich nicht irre.Es erfordert ein bisschen mehr Arbeit im Voraus, ist aber einfacher zu bedienen.

class Program 
{ 
    static void Main(string[] args) 
    { 
     var myClass = new MyClass(); 
     myClass.DoWork(); 
     Console.ReadKey(); 
    } 
} 

public static class ObjectThreadExtension 
{ 
    public static void OnThread(this object @object, Action action) 
    { 
     ThreadPool.QueueUserWorkItem(state => 
     { 
      action(); 
     }); 
    } 

    public static void OnThread<T>(this object @object, Action<T> action, T argument) 
    { 
     ThreadPool.QueueUserWorkItem(state => 
     { 
      action(argument); 
     }); 
    } 
} 

public class MyClass 
{ 
    private void MyMethod() 
    { 
     Console.WriteLine("I could have been put on a thread if you like."); 
    } 

    private void MySecondMethod(string argument) 
    { 
     Console.WriteLine(argument); 
    } 

    public void DoWork() 
    { 
     this.OnThread(MyMethod); 
     this.OnThread(MySecondMethod, "My argument"); 
    } 
} 
+0

Das wäre ein Gewinner für mich, wenn es nicht Signatur-restriktiv wäre. Aber immer noch irgendwie cool, um es nur eine Methode zu geben und damit fertig zu sein. – Bitterblue

+0

@Bitterblue Ich habe einen zweiten Ansatz hinzugefügt. Ein bisschen mehr Arbeit im Voraus, aber meiner Meinung nach am einfachsten. –