2013-07-02 9 views
19

ちょうど今、次のコードを使用してキューに入れられたスレッドを追加しています。私はそれが気に入りません。そして、私の同僚は、C#をよく理解していないからといって、どちらにもなりません。私が望むのはもちろん、新しいスレッドで実行されるメソッドをキューに入れることです。C# - ThreadPool QueueUserWorkItem使用しますか?

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

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

のでThreadPool.QueueUserWorkItemの他の使用バリエーションがあるのですか?

ベストは別の1-Line-Callです。可能であればFunc<>またはAction<>を使用してください。


編集:回答とコメントから(b)を取得しました。

+2

シナリオでThreadPool.QueueUserWorkItem()に問題がありますか? –

+1

「委任」キーワードを使用できます。何かのように、ThreadPool.QueueUserWorkItem(delegate {doStuff( "");})。上記の方法と同じですが、望むように、これは別の方法です。 –

+1

なぜ、デリゲートの構文がlambdasよりもクリーンだと思いますか? –

答えて

12

質問に対する回答は、アプリケーションの設計方法によって異なります。共通のプロジェクトの中に入れますか?オーバーヘッドに単純な操作をしたくないです。

しかし、params、1 param、2 paramなどを受け取るThreadPool QueueUserItemの汎用呼び出しを作成することができます。これは単純な文字列を送信するのではなく、制限することができます。

あなたはWaitCallbackでパラメータをQueueUserItem IMPLどのようにこの:

C# Execute Method (with Parameters) with ThreadPool

から取ら

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

やアイデアのためのいくつかのリンク:このことについて
http://msdn.microsoft.com/en-us/library/4yd16hza.aspx
Generic ThreadPool in .NET
Difference between delegate.BeginInvoke and using ThreadPool threads in C#

+0

これは 'Func'や' Action'でも可能ですし、余分な呼び出し体を使わなくてもかまいませんか? – Bitterblue

+0

これは可能ですが、WaitCallbackをビルドするときは、単純な「デリゲート」を送信せず、代わりに独自のデリゲートを送信してください。 *しかし*、あなたはどのように結果を戻すことを期待していますか?通常、ワーカースレッドに操作を送信するときは、結果が得られるとは予想せず、ジョブが完了したことを確認するだけです。これを実現するには、非同期パターンを実装します。 http://www.c-sharpcorner.com/UploadFile/rmcochran/multithreadasyncwebservice05262007094719AM/multithreadasyncwebservice.aspx – ilansch

13

あなたが探している構文の種類は完全にはわかりませんが、使用していないaが好きでない場合は、代わりにTaskを使用してください。

Task.Run(() => doStuff("hello world")); 

実際にはあまり良くはありませんが、少なくとも未使用の識別子はありません。

注:Task.Run()は.Net 4.5以降です。 .Net 4を使用している場合:

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

これは短くはありません。

上記のどちらもスレッドプールを使用します。

あなたは本当にラムダの使用を避ける必要がある場合は、(すでに述べた@nowhewhomustnotbenamed)匿名デリゲートを使用することができます

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

をしかし、それのポイントは何ですか?それははるかに読みにくいです!

+0

実際に私はラムダ事を避けたいです。 – Bitterblue

+0

@ mini-meラムダの使用を避ける例を追加しました...それはもっと悪いです、IMO。 –

+9

@ mini-meラムダ式はかなり前に匿名の代理人を置き換えました。だから、あなたは後ではなく早く彼らに慣れるためにうまくいくでしょう。 – nashwan

2

何?

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

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

それとも、署名の制限になりたいとあなたが値を返さないと、最大6に持ってthis.Forメソッドのようにそれを行うことができますスレッド上のメソッドを置くの簡単な方法を持っていない場合私が間違っていない場合は、12の過負荷を定義する必要があります。もう少し作業が必要ですが、使用するのがより簡単です。

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

このような署名が制限されていない場合、これは私の勝者になるでしょう。しかし、まだちょっと冷たくて、それに方法をつけてやってみてください。 – Bitterblue

+0

@Bitterblue 2番目のアプローチを追加しました。私の意見では、もう少し前から作業していますが、使い方が簡単です。 –

関連する問題