2014-02-25 2 views
-1

데이터베이스를 쿼리하고 언젠가 반환하는 비동기 메서드입니다. 내가 구문 능숙하지 오전하지만 비동기 쿼리를 수행 한 후 제가이 필요하면 두 푸 메소드가 호출되는있는 방법으로 위의 코드를 변경하는 것입니다콜백 동작을 메서드에 전달

 this.Model.GetStudentKeys(keysList); 
     this.Foo1(); 
     this.Foo2(); 

: 현재는이 같은 것입니다 . 따라서 저는 다음과 같은 것이 필요하다는 것을 알고 있습니다.

그러나 제가 구문에 익숙하지 않다고 말하면서 도와 주시겠습니까? GetStudentKeys 방법을 가정

+0

다음과 같이

//notice the 'async' keyword and generic 'Task(T)' return type public async Task<IEnumerable<StudentModel>> GetStudentsAsync(IEnumerable<int> keyList) { /*to invoke async methods, precede its invocation with the 'await' keyword. This allows program flow to return the line on which the GetStudentsAsync method was called. The flow will return to GetStudentsAsync once the database operation is complete.*/ IEnumerable<StudentModel> students = await FakeDatabaseService.ExecuteSomethingAsync(); return students; } 

은 단순히 위의 메소드를 호출? – rae1

+0

@ rae1 아니오, 정상적인 콜백 만 추가하면 Foo 메소드를 넣을 수 있습니다. –

+0

글쎄, 내가 대답에서 언급 한 것처럼, 그 자체가 비동기 적이어야한다. – rae1

답변

2

콜백을 사용할 수 있지만 은 C#의 async/await syntax으로 대체됩니다. 내가 구문 그러나 말했다 설명하기 전에, 당신이 Action들과 같은를 달성 할 수있는 방법을 보여 드리겠습니다 :이 방법으로

/*Action is a reference type, so its assignment is no different. Its value is a lambda 
    expression (http://msdn.microsoft.com/en-us/library/bb397687.aspx), 
    which you can think of as an anonymous method.*/ 
private Action<object> callback = o => 
          { 
           object result = o; 

           this.Foo1(); 
           this.Foo2(); 
          }; 

/*It's good practice in C# to append 'Async' to the name of an asynchronous method 
    in case a synchronous version is implemented later.*/ 
this.Model.GetStudentKeysAsync(keysList, callback); 

, 당신의 GetStudentsAsync 방법과 같이 콜백을 호출해야합니다 :

public void GetStudentsAsync(List<string> keys, Action<object> callback) 
{ 
    var returnValue = null; 
    //do some stuff... 
    callback(returnValue); 
} 

또한 직접 매개 변수로 람다 식을 전달할 수 있지만

.NET 4.5 (4.0 및 .NET Microsoft Async package 사용)
this.Model.GetStudentKeysAsync(keysList, o => 
          { 
           this.Foo1(); 
           this.Foo2(); 
          }); 

, 당신은 C# 5에서 제공하는 asyncawait 키워드를 사용할 수 있습니다 : 당신은`async`와`await` 같은 것을 사용하여 의미

IEnumerable<StudentModel> students = await this.Model.GetStudentsAsync(keyList); 
+0

정확하게 첫 번째 접근 방식에서 필요한 것. 새로운 C#에 대한 추가 정보를 보내 주셔서 감사합니다. –

+0

여러분, 반갑습니다. 기꺼이 도와 드리겠습니다! :) –

1

비동기 작업이 완료되면, 당신은

public async void MethodName() 
{ 
    await this.Model.GetStudentKeysAsync(keysList); // <-- Async operation 
    this.Foo1(); 
    this.Foo2(); 
} 

, asyncawait을 구성 (5.0 C#으로 신규) 코드를 사용할 수 (그것 때문에 비동기 인까지) Task 객체를 반환 await 키워드 다음에 계속됩니다.

+0

죄송합니다. 그것은 IQueryable을 리턴한다. –

+0

그런 다음 메소드를 먼저 async로 만들어야한다. 작업 자체가 현재 스레드를 차단하는 경우 콜백을 추가해도 상관 없습니다. – rae1

1

당신은 그

void GetStudentKeys(keysList, Func<bool> callback) 
    { 
     Thread th = new Thread(delegate(){ 
      //do some work in separate thread and inside that thread call 
      if(callback != null) 
       callback(); 
     }); 
     th.Start(); 
    } 

처럼 함수를 정의하고 그런

this.Model.GetStudentKeys(keysList,() => { 
     this.Foo1(); 
     this.Foo2(); 
     return true; 
    }); 

뭔가에 함수 호출을 변경할 수 있습니다.