2013-04-05 4 views
4

"동기 코드"(즉, 다른 스레드가 무언가를 끝낼 때까지 기다리기 위해 Windows 이벤트를 사용함)를 리팩토링하는 프로세스에서 "비동기"코드로 구현합니다. 콜백 메카니즘).C# 또는 VB.NET에서 std :: bind equivalent

동기화 코드에서 대기가 끝난 후 사용해야 할 지역 변수가 있습니다. 이와 같은 코드가 비동기가되면 해당 로컬 변수가 손실됩니다 (콜백 핸들러가 해당 코드에 액세스 할 수 없음). 클래스 속성으로 저장할 수는 있지만 낭비입니다.

C++에서이 문제를 해결하기 위해 std::bind을 사용합니다. 콜백 처리기에 필요한 로컬 변수만큼의 매개 변수를 추가하고 비동기 메서드를 호출 할 때 바인딩합니다. 예를 들어 비동기 메서드 콜백이 CallbackParam 유형의 객체를 받고 호출자가 LocalALocalB 유형의 두 로컬 변수를 사용한다고 가정 해 봅시다.

void AsyncClass::MethodWhichCallsAsyncMethod(){ 
    LocalA localVarA; 
    LocalB localVarB; 
    // OnAsyncMethodDone will need localVarA and localVarB, so we bind them 
    AsyncMethod(std::bind(&AsyncClass::OnAsyncMethodDone, this, std::placeholders::_1, localVarA, localVarB)); 
} 

void AsynClass::AsyncMethod(std::function<void(CallbackParam)> callback){ 
    CallbackParam result; 
    //Compute result... 
    if(callback) 
     callback(result); 
} 

void AsyncClass::OnAsyncMethodDone(CallbackParam p, LocalA a, LocalB b){ 
    //Do whatever needs to be done 
} 

C# 및 VB.NET에서 이와 비슷한 기능이 있습니까? 델리게이트 또는 다른 것을 사용하고 있습니까?

UPDATE :

using System; 

public class AsyncClass { 

     public void MethodWhichCallsAsyncMethod() { 
      var a = new LocalA(); 
      var b = new LocalB(); 
      //Anonymous callback handler (equivalent to AsyncClass::OnAsyncMethodDone) 
      Action<CallbackParam> callback = result => { 
       //Do what needs to be done; result, a and b can be accessed 
      }; 
      AsyncMethod(callback); 
     } 

     private void AsyncMethod(Action<CallbackParam> callback) { 
      var result = new CallbackParam(); 
      //Compute result... 
      if(callback != null) 
       callback(result); 
     } 
} 

답변

3

UPDATE : 완성도를 들어 '술, 여기 @의 lasseespeholt의 답변에 따라 내 예제의 C#을 동등이 거의 확실 사용할 수 없습니다. 비동기를 사용하여/

당신은 다음과 같은 폐쇄 이용할 수있는 C#에서 키워드를 기다리고 :이 방법에 아무것도 저장하지 않도록 "foo는"이 포함되어

void MethodWhichCallsAsyncMethod() 
{ 
    int foo = 1; 

    AsyncCallback callback = result => 
    { 
     Console.WriteLine(foo); // Access to foo 
    }; 

    AsyncMethod(callback); 
} 

void AsyncMethod(AsyncCallback callback) 
{ 
    IAsyncResult result = null; // Compute result 
    callback(result); 
} 

컴파일러를 생성하는 클래스를하지만, 깨끗합니다.

+0

멋집니다. 내 클래스에 상태를 추가하는 것을 꺼려했지만 컴파일러가 그것을 수행하면 나는 괜찮습니다 : P VB.NET에서도이 작업을 수행 할 수 있습니까? (우리는 .NET 4.0을 말하고 있습니다.) –

+1

@dario_ramos VB.Net은 사용하지 않지만 예. C#과 VB.Net은 대부분의 기능을 공유합니다. 이 페이지는 VB.Net에서 lambdas를 사용하는 데 도움이됩니다. http://msdn.microsoft.com/en-us/library/bb531253.aspx –