2012-06-15 5 views
3

리플렉션을 사용하여 비동기 메소드를 만들려면 어떻게해야합니까?리플렉션을 사용한 비동기 프로그래밍

기본적으로 나는 이런 식으로 뭔가가 필요합니다

async public Task asyncmethod() 
{ 
    await something(); 
} 

을하지만 난 반사와 함께 할 필요가있다.

+0

async/await를 사용하는 이유는 무엇입니까? something()이 작업을 반환하면 Wait를 호출하면됩니다. –

+2

@PanagiotisKanavos 이렇게하면 메서드를 동기식으로 만들 것이므로이를 피하면 'async'의 전체 점이됩니다. – svick

+0

리플렉션을 통해 메서드를 만들 수 없으면 호출 할 수 있습니다. –

답변

6

async 메서드의 변환은 C# (또는 VB.NET) 컴파일러 수준에서 작동하지만 CIL에서는 지원되지 않습니다. 어떤 컴파일러는 간단한 경우에서하는 것은이 같은 코드를 변환하는 것입니다 :

과 같이 기본적으로 동등 코드로
async public Task asyncmethod() 
{ 
    // some code 
    var x = await something(); 
    // more code 
} 

:

public Task asyncmethod() 
{ 
    // some code 
    return something().ContinueWith(
     t => 
     { 
      var x = t.Result; 
      // more code 
     }); 
} 

실제 코드는 훨씬 더 복잡 그 그 (IS SynchronizationContext을 사용합니다. 실제로가 반환 된 경우 Task이 반환되면 Task에 감사하는 await을 지원합니다. 더 복잡한 C# 코드의 경우 더욱 복잡해집니다.

그러나 실제로 Reflection.Emit을 사용하여 async 메쏘드를 만들고 싶다면이 변환은 실제로 수동으로해야합니다.

public Task asyncmethod() 
{ 
    // some code 
    return something(); 
} 
:주의해야 할

그러나 한 가지는 당신의 방법은 await 한 번만 바로 전에 return의를 사용하는 경우, 당신은 (something() 반환 할 수 await입니다 그 밖에 Task이 아닌 뭔가를 가정)으로 재 작성 할 수 있다는 것입니다

+0

컴파일러가 비동기로 코드를 변환하는 방법에 대한 자세한 정보를 어디에서 찾을 수 있습니까?코드가 더 복잡하더라도 작업 이외의 것들을 기다리고 싶습니다. – mertin

+1

현재 상황을 설명하는 하나의 최종 소스가 확실하지 않습니다. 가장 좋은 옵션은 C# 5.0 사양이지만 아직 출시되지 않았습니다. [async'에 대한 명세] (http://www.microsoft.com/en-us/download/details.aspx?id=23753), [Eric Lippert의 기사] (http : // blogs.msdn.com/b/ericlippert/archive/tags/c_2300_+5-0/) 및 [Jon Skeet의 다른 시리즈 기사] (http://msmvps.com/blogs/jon_skeet/archive/tags/async/ default.aspx). – svick

+0

하지만 대부분이 CTP에 대해 이야기하고 상황은 그 이후로 다소 바뀌 었습니다. Jon Skeet의 시리즈 중 18 번과 20 번에서는 CTP와 DP, DP와 베타 사이의 변경 사항에 대해 설명하고 있습니다. – svick

1

질문을 구문 분석하는 다른 방법은 메서드 내에서 리플렉션을 사용해야하지만 (예 : 개인 메서드에 액세스하는 경우) 여전히 대기 상태를 사용하고 싶다는 것입니다.

그럴 경우 일반적으로 평소처럼 리플렉션을 사용하여 작업 (또는 무엇을 기다릴 수있는 것이 든)을 되찾은 다음 별도로 기다릴 수 있습니다. 같은

뭔가 : svick 언급으로 만 AWAIT가 끝에있는 경우, 다만 방법 비동기를 표시하고 await를 사용하는 대신 작업을 반환하지만

public async Task asyncmethod() 
{ 
    Task t = ... // code that fetches the Task via reflection 
    await t; 
} 

.