2009-05-06 10 views
31

誰もが複数のパラメータをThread.Startルーチンに渡す方法を知っていますか?複数のパラメータを持つスレッド

私はクラスを拡張することを考えましたが、C#Threadクラスはシールされています。

... 
    Thread standardTCPServerThread = new Thread(startSocketServerAsThread); 

    standardServerThread.Start(orchestrator, initializeMemberBalance, arg, 60000); 
... 
} 

static void startSocketServerAsThread(ServiceOrchestrator orchestrator, List<int> memberBalances, string arg, int port) 
{ 
    startSocketServer(orchestrator, memberBalances, arg, port); 
} 

はところで、私は別のオーケストレータ、残高およびポートを備えたスレッドの数を開始します。ここでは

は、私は次のようなコードが見えると思うものです。スレッドの安全性も考慮してください。

答えて

56

に必要

は、引数をキャプチャするためにラムダ式を使用してみてください。

Thread standardTCPServerThread = 
    new Thread(
    unused => startSocketServerAsThread(initializeMemberBalance, arg, 60000) 
); 
+0

独立したスレッドで式を実行するのはどれだけ安全ですか? –

+7

これは安全です - 注意点があります。しかし、これを呼び出すとすぐに変数を微調整すると、変数を実際に参照渡ししているので、いくつかの奇妙な副作用が生じる可能性があります。 –

+0

スレッドを安全にする方法に関するアイデアはありますか? –

11

単一のオブジェクトにラップする必要があります。

パラメータを渡すカスタムクラスを作成することも選択肢の1つです。配列やオブジェクトのリストを使用して、その中のすべてのパラメータを設定することもできます。

3

できません。必要なパラメータを含むオブジェクトを作成し、それを渡します。スレッド関数では、オブジェクトをその型にキャストし直します。

1

Object配列をとり、スレッド内で渡すことができます。合格。

System.Threading.ParameterizedThreadStart(yourFunctionAddressWhichContailMultipleParameters) 

スレッドコンストラクタにイント。

yourFunctionAddressWhichContailMultipleParameters(object[]) 

すでにすべての値をobjArrayに設定しています。あなたはabcThread.Start(objectArray)

0

あなたは、ラムダ式で「仕事」機能をカレーができます

public void StartThread() 
{ 
    // ... 
    Thread standardTCPServerThread = new Thread(
     () => standardServerThread.Start(/* whatever arguments */)); 

    standardTCPServerThread.Start(); 
} 
+0

mmmmラムカレー。 – Pete

7

は、「タスク」パターンを使用します。

public class MyTask 
{ 
    string _a; 
    int _b; 
    int _c; 
    float _d; 

    public event EventHandler Finished; 

    public MyTask(string a, int b, int c, float d) 
    { 
     _a = a; 
     _b = b; 
     _c = c; 
     _d = d; 
    } 

    public void DoWork() 
    { 
     Thread t = new Thread(new ThreadStart(DoWorkCore)); 
     t.Start(); 
    } 

    private void DoWorkCore() 
    { 
     // do some stuff 
     OnFinished(); 
    } 

    protected virtual void OnFinished() 
    { 
     // raise finished in a threadsafe way 
    } 
} 
9

ここで使用するコードのビットがオブジェクト配列のアプローチは、ここで数回述べた。 JaredParの

... 
    string p1 = "Yada yada."; 
    long p2 = 4715821396025; 
    int p3 = 4096; 
    object args = new object[3] { p1, p2, p3 }; 
    Thread b1 = new Thread(new ParameterizedThreadStart(worker)); 
    b1.Start(args); 
    ... 
    private void worker(object args) 
    { 
     Array argArray = new object[3]; 
     argArray = (Array)args; 
     string p1 = (string)argArray.GetValue(0); 
     long p2 = (long)argArray.GetValue(1); 
     int p3 = (int)argArray.GetValue(2); 
     ... 
    }> 
+0

@Opusラムダ式、JaredParの解法は、維持するのが簡単だと思う(読んで、理解し、更新する) –

5

.NET 2変換私はそれを行う方法を見つけるためにあなたのフォーラムを読んでいると私はそのようにそれをやった

Thread standardTCPServerThread = new Thread(delegate (object unused) { 
     startSocketServerAsThread(initializeMemberBalance, arg, 60000); 
    }); 
2

に答える - 誰かのために役に立つかもしれません。私は自分のメソッドを実行する私のためのスレッドを作成するコンストラクタの引数を渡します - execute()メソッド。

using System; 

using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Diagnostics; 
using System.Windows.Forms; 
using System.IO; 
using System.Threading; 
namespace Haart_Trainer_App 

{ 
    class ProcessRunner 
    { 
     private string process = ""; 
     private string args = ""; 
     private ListBox output = null; 
     private Thread t = null; 

    public ProcessRunner(string process, string args, ref ListBox output) 
    { 
     this.process = process; 
     this.args = args; 
     this.output = output; 
     t = new Thread(new ThreadStart(this.execute)); 
     t.Start(); 

    } 
    private void execute() 
    { 
     Process proc = new Process(); 
     proc.StartInfo.FileName = process; 
     proc.StartInfo.Arguments = args; 
     proc.StartInfo.UseShellExecute = false; 
     proc.StartInfo.RedirectStandardOutput = true; 
     proc.Start(); 
     string outmsg; 
     try 
     { 
      StreamReader read = proc.StandardOutput; 

     while ((outmsg = read.ReadLine()) != null) 
     { 

       lock (output) 
       { 
        output.Items.Add(outmsg); 
       } 

     } 
     } 
     catch (Exception e) 
     { 
      lock (output) 
      { 
       output.Items.Add(e.Message); 
      } 
     } 
     proc.WaitForExit(); 
     var exitCode = proc.ExitCode; 
     proc.Close(); 

    } 
} 
} 
2
void RunFromHere() 
{ 
    string param1 = "hello"; 
    int param2 = 42; 

    Thread thread = new Thread(delegate() 
    { 
     MyParametrizedMethod(param1,param2); 
    }); 
    thread.Start(); 
} 

void MyParametrizedMethod(string p,int i) 
{ 
// some code. 
} 
0

あなたは、単一のオブジェクトを渡す必要があるが、それは、単一の使用のために、独自のオブジェクトを定義するにはあまりにも面倒だ場合、あなたはタプルを使用することができます。

+0

mcmillabの使用例? –

関連する問題