2011-07-01 2 views

답변

13

2.

죄송합니다 .NET 용 난 당신이 작업을 다시 할 해달라고 말했다 알고 있지만, 실제로는 Task 객체와 같이 동작하는 클로저를 사용하여 매우 간단하게 무언가를 만들 수 있습니다. .

public delegate R AsyncTask<R>(); 

    public static AsyncTask<R> BeginTask<R>(AsyncTask<R> function) 
    { 
     R retv = default(R); 
     bool completed = false; 

     object sync = new object(); 

     IAsyncResult asyncResult = function.BeginInvoke(
       iAsyncResult => 
       { 
        lock (sync) 
        { 
         completed = true; 
         retv = function.EndInvoke(iAsyncResult); 
         Monitor.Pulse(sync); 
        } 
       }, null); 

     return delegate 
     { 
      lock (sync) 
      { 
       if (!completed)    
       { 
        Monitor.Wait(sync); 
       } 
       return retv; 
      } 
     }; 
    } 

그것의 당신이 통과 대리인에 BeginInvoke()를 호출하고 블록을 불러 전달 된 함수의 결과를 대기하는 함수를 반환하는 함수 당신은 좋겠 : 이것은 내가 무엇을 사용 물론 다른 메소드 시그니처에 대해이 함수의 오버로드를 작성해야합니다.

한 가지 방법은 필요에 맞게 조정할 수 있으며 Continuations 등과 같은 다른 동작을 추가하는 것입니다. 핵심은 클로저와 익명의 대리자를 사용하는 것입니다. .NET 2.0에서 작동해야합니다.

편집 - 여기 당신이 그것을 사용하는 것이 방법입니다

public static string HelloWorld() 
    { 
     return "Hello World!"; 
    } 

    static void Main(string[] args) 
    { 
     var task = BeginTask(HelloWorld); // non-blocking call 

     string result = task(); // block and wait 

    } 
+0

감사합니다. 이것은 좋은 출발점입니다. –

+0

코드를 살펴볼 때 BeginInvoke는 위에서 사용 된 HelloWorld를 [관리되는 스레드 풀의 새 스레드]에서 시작합니다 (http://stackoverflow.com/questions/3556634/does-funct-begininvoke-use-the-threadpool).). – rkagerer

4
당신은 System.Threading.Thread 클래스를 사용해야합니다

, 당신은 .NET 3.5의 Task 클래스를 얻을 수 있지만

+0

내가 작업 클래스 I 3.5에서 사용할 수있는 방법 .NET 4와 함께 제공 인상을했다? –

+2

[Rx] (http://go.microsoft.com/fwlink/?LinkID=179929) 팀은 .NET 3.5 SP1로 'Task'및 기타 낮은 수준의 추상화 (전체 TPL 제외)를 백 포트했습니다. –

+0

@Christial Schwarz, Stephen이 말했듯이, 그것은 백 포트되었습니다. – Jethro

관련 문제