2009-05-06 4 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); 
} 

가 BTW, 내가 다른 관현악, 균형 및 포트 스레드 수를 시작 : 여기

내가 같은 코드가 보일 것이다 생각합니다. 스레드 안전성을 고려하십시오.

답변

56

해야합니다.

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

별도의 스레드에서 표현식을 실행하는 것이 얼마나 안전합니까? –

+7

이것은 안전합니다.변수를 호출 한 후 즉시 변수를 조정하면 변수를 참조로 효과적으로 전달하기 때문에 이상한 부작용이 생길 수 있습니다. –

+0

스레드를 안전하게 만드는 방법에 대한 아이디어가 있으십니까? –

11

단일 개체로 묶어야합니다.

매개 변수를 전달할 사용자 지정 클래스를 만드는 것이 하나의 옵션입니다. 또한 배열이나 객체 목록을 사용하고 그 안에 모든 매개 변수를 설정할 수 있습니다.

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)의 솔루션 인 람다 (lambda) 표현이 유지 보수하기가 더 쉽다고 생각합니다 (읽기, 이해 및 업데이트) –

5

.NET이 변환은 내가 그것을 할 방법을 찾아 당신의 포럼을 읽어 봤는데

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의 작동 예제는 무엇입니까? –