2010-04-15 2 views
5

내가 aruguments와 스레드에서 메서드를 호출하고 aruguments와 스레드에서 메서드를 호출하고 어떤 값을 반환하는 방법을

class Program 
    { 
     static void Main() 
     { 
      Thread FirstThread = new Thread(new ThreadStart(Fun1)); 
      Thread SecondThread = new Thread(new ThreadStart(Fun2)); 
      FirstThread.Start(); 
      SecondThread.Start();   


     } 
     public static void Fun1() 
     { 
      for (int i = 1; i <= 1000; i++) 
      { 
       Console.WriteLine("Fun1 writes:{0}", i); 
      } 
     } 
     public static void Fun2() 
     { 
      for (int i = 1000; i >= 6; i--) 
      { 
       Console.WriteLine("Fun2 writes:{0}", i); 
      } 
     } 

    } 

내가이 위의 예제를 성공적으로 알고 어떤 여기에 값 예를 반환하지만 경우에 같은 방법 fun1 like이

public int fun1(int i,int j) 
{ 
    int k; 
    k=i+j; 
    return k; 
} 

내가 어떻게 스레드에서 이것을 호출 할 수 있습니다. me..i 모든 가능한 방법이 필요 것이 가능 .ANY 몸에 도움이됩니다이

+0

이 예제가 충분하다고 생각합니다. 이 답변이 귀하의 기대치와 일치하지 않으면, 전체 시나리오와 필요한 것을 제공하십시오. – Mohanavel

답변

6

이것은 다른 접근 방법 일 수 있습니다. 여기서 입력은 매개 변수화 된 스레드로 전달되고 반환 유형은 대리자 이벤트에서 전달되므로 스레드 완료시 대리인이 호출됩니다. 스레드가 완료되면 결과를 얻는 것이 좋을 것입니다.

public class ThreadObject 
    { 
     public int i; 
     public int j; 
     public int result; 
     public string Name; 
    } 



    public delegate void ResultDelegate(ThreadObject threadObject); 

    public partial class Form1 : Form 
    { 

     public event ResultDelegate resultDelete; 

     public Form1() 
     { 
      InitializeComponent(); 

      resultDelete += new ResultDelegate(resultValue); 
     } 

     void resultValue(ThreadObject threadObject) 
     { 
      MessageBox.Show("Thread Name : " + threadObject.Name + " Thread Value : " + threadObject.result); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      ThreadObject firstThreadObject = new ThreadObject(); 
      firstThreadObject.i = 0; 
      firstThreadObject.j = 100; 
      firstThreadObject.Name = "First Thread"; 

      Thread firstThread = new Thread(Fun); 
      firstThread.Start(firstThreadObject); 


      ThreadObject secondThreadObject = new ThreadObject(); 
      secondThreadObject.i = 0; 
      secondThreadObject.j = 200; 
      secondThreadObject.Name = "Second Thread"; 

      Thread secondThread = new Thread(Fun); 
      secondThread.Start(secondThreadObject); 

     } 


     private void Fun(object parameter) 
     { 
      ThreadObject threadObject = parameter as ThreadObject; 

      for (; threadObject.i < threadObject.j; threadObject.i++) 
      { 
       threadObject.result += threadObject.i; 

       Thread.Sleep(10); 
      } 

      resultValue(threadObject); 
     } 
    } 
24

당신은 전체 정적 검사를 제공하기 위해 익명 메서드 또는 람다를 사용할 수 있어야합니다 :

Thread FirstThread = new Thread(() => Fun1(5, 12)); 

또는 당신이 원하는 경우를 결과와 함께 뭔가를 할 :

Thread FirstThread = new Thread(() => { 
    int i = Fun1(5, 12); 
    // do something with i 
}); 

을하지만 참고 "캡처 변수이 여전히 새 스레드의 컨텍스트에서 실행"무언가를 "(그러나 외부 방법에서 다른 변수에 접근 할 수있는 (Main) 예의 "). 다음

(위가 아니라) C# 2.0이있는 경우

는 :

Thread FirstThread = new Thread((ThreadStart)delegate { Fun1(5, 12); }); 

Thread FirstThread = new Thread((ThreadStart)delegate { 
    int i = Fun1(5, 12); 
    // do something with i 
}); 
+0

다른 방법을 사용할 수 있으면 감사드립니다 ... – ratty

+0

@ratty - 정확히 무엇을 하시겠습니까? –

0

당신은 스레드 생성자에 ParameterizedThreadStart 과부하를 사용할 수 있습니다. Object를 매개 변수로 스레드 메서드에 전달할 수 있습니다. 이것은 하나의 Object 매개 변수가 될 것이므로 일반적으로 이러한 스레드에 대한 매개 변수 클래스를 만듭니다.이 개체는 스레드 실행이 끝난 후에 읽을 수있는 스레드 실행 결과를 저장할 수도 있습니다.

스레드가 실행되는 동안이 개체에 액세스하는 것이 가능하지만 "스레드 안전"이 아닙니다. 당신은 드릴 : 여기

를 예를 들어 것을 알고 : 몇 가지 대안을

void Main() 
{ 
    var thread = new Thread(Fun); 
    var obj = new ThreadObject 
    { 
     i = 1, 
     j = 15, 
    }; 

    thread.Start(obj); 
    thread.Join(); 
    Console.WriteLine(obj.result); 
} 

public static void Fun(Object obj) 
{ 
    var threadObj = obj as ThreadObject; 
    threadObj.result = threadObj.i + threadObj.j; 
} 

public class ThreadObject 
{ 
    public int i; 
    public int j; 
    public int result; 
} 
0

; 태닝 :

static ThreadStart CurryForFun(int i, int j) 
{ // also needs a target object if Fun1 not static 
    return() => Fun1(i, j); 
} 

Thread FirstThread = new Thread(CurryForFun(5, 12)); 

또는 자신의 캡처 형 쓰기 (이것은 당신이 곧-방법/캡처 변수 람다를 사용할 때 컴파일러가 당신을 위해 무엇을 대체로 비슷하지만 다르게 구현 된) :

class MyCaptureClass 
{ 
    private readonly int i, j; 
    int? result; 
    // only available after execution 
    public int Result { get { return result.Value; } } 
    public MyCaptureClass(int i, int j) 
    { 
     this.i = i; 
     this.j = j; 
    } 
    public void Invoke() 
    { // will also need a target object if Fun1 isn't static 
     result = Fun1(i, j); 
    } 
} 
... 
MyCaptureClass capture = new MyCaptureClass(5, 12); 
Thread FirstThread = new Thread(capture.Invoke); 
// then in the future, access capture.Result 
1

별도의 스레드에서 함수를 실행 훨씬 간단한 방법이 있습니다 :

// Create function delegate (it can be any delegate) 
var FunFunc = new Func<int, int, int>(fun1); 
// Start executing function on thread pool with parameters 
IAsyncResult FunFuncResult = FunFunc.BeginInvoke(1, 5, null, null); 
// Do some stuff 
// Wait for asynchronous call completion and get result 
int Result = FunFunc.EndInvoke(FunFuncResult); 

이 기능은 스레드 풀 스레드에서 실행하고, 그 논리는 응용 프로그램에 완전히 투명합니다. 일반적으로 전용 스레드 대신 스레드 풀에서 이러한 작은 작업을 실행하는 것이 좋습니다.

7

마크 그래벨의 대답을 좋아합니다. 약간의 수정만으로 결과를 메인 스레드로 전달할 수 있습니다.

int fun1, fun2; 
Thread FirstThread = new Thread(() => { 
    fun1 = Fun1(5, 12); 
}); 
Thread SecondThread = new Thread(() => { 
    fun2 = Fun2(2, 3); 
}); 

FirstThread.Start(); 
SecondThread.Start(); 
FirstThread.Join(); 
SecondThread.Join(); 

Console.WriteLine("Fun1 returned {0}, Fun2 returned {1}", fun1, fun2); 
관련 문제