2012-12-18 2 views
1

다음 코드는 컴파일되지 않습니다. 나는 오류작업 병렬 라이브러리를 통해 작업을 만들 때 람다에서 'out'을 사용하십시오.

가 심판 또는 매개 변수 'messageLockToken'에서 익명 메소드 내부 람다 식 또는 쿼리 식 내가 람다에 새로 온 사람과에 대해 조금 혼란 스러워요 인정

를 사용할 수 없습니다를 얻을 이 문제를 해결합니다. 누구든지 컴파일러 허용 방식으로 아래 논리를 표현할 수있는 방법을 알고 있습니까?

public T Receive<T>(TimeSpan receiveTimeout, out Guid messageLockToken) 
{ 
    // do work 
} 

public Task<T> ReceiveAsync<T>(TimeSpan receiveTimeout, out Guid messageLockToken) 
{ 
    Task<T> sendQueueMsgTask = new Task<T>(() => Receive<T>(receiveTimeout, out messageLockToken)); 
    return sendQueueMsgTask; 
} 
+0

어떤 언어입니까? –

+0

C#, .NET 당 최신 구현 – DeepSpace101

답변

1

먼저 컴파일 한 경우에도 메서드가 작동하지 않습니다. new Task()을 사용할 때 항상 에 Start()을 호출해야합니다 (또는 Task.Run()을 사용).

여기서는 out 매개 변수를 사용할 수 없습니다. 왜냐하면이 매개 변수는별로 의미가 없기 때문입니다. 메서드에서 즉시 Task을 반환하려고하지만 이는 즉 Guid을 즉시 반환하는 것을 의미합니다. 즉, Receive() 전화가 out 매개 변수의 값에 실제로 영향을 미치지 않습니다.

public Task<Tuple<T, Guid>> ReceiveAsync<T>(TimeSpan receiveTimeout) 
{ 
    return Task.Run(
     () => 
     { 
      Guid messageLockToken; 
      var result = Receive<T>(receiveTimeout, out messageLockToken); 
      return Tuple.Create(result, messageLockToken); 
     }); 
} 

이것은 당신이 실제로 가지 이유 스티븐 Toub의 기사 Should I expose asynchronous wrappers for synchronous methods? 볼이 작업을 수행 할 가정

나는 여기에 방법을 Tuple (Rawling가 제안) 또는 사용자 정의 반환 형식이다 사용하여 생각 이렇게하는 것은 좋은 생각이 아닙니다.

0

당신이 여기 out 매개 변수를 사용할 수 없기 때문에, 대신 당신은 할 수 :

  • 돌려 Tuple<T, Guid> (또는 사용자 정의 제네릭 클래스 사용) 또는
  • 을보다는 Action<Guid>을 통과 out Guid (그래서 오히려 ReceiveAsync(ts, out myGuid)보다는 당신이 ReceiveAsync(ts, g => myGuid = g) 전화 것)

거기 (나는 생각하지 않는다 어떤 식 으로든 호출자에게 out 매개 변수를 노출시키기 위해이 문제를 해결할 수 있습니다. 메서드가 반환 될 때 out 매개 변수가 채워지기로되어 있지만이 경우 사실이 아닐 수 있습니다.

+0

두 번째 방법은 람다가 정확히 호출 될 때 명확하지 않기 때문에 혼란 스럽습니다. – svick

+0

@svick'Task'의 람다가'out'을 허용 한 것과 같은 행동이지만, "작업이 완료 될 때까지이 guid를 설정하십시오"라고 동의합니다. – Rawling

관련 문제