2016-10-06 5 views
2

I (비동기) 작업을 구현하기 위해 저를 강제하는 인터페이스가 있습니다는 비동기 메소드를 구현 기적

namespace Microsoft.Owin.Security.Infrastructure 
{ 
    public interface IAuthenticationTokenProvider 
    { 
     .. 
     Task CreateAsync(AuthenticationTokenCreateContext context); 
     .. 
    } 
} 

나는이 방법을 구현하고자하지만 난 아무것도 기다리고 아니에요을. 나는 몇 가지 작업을 뭔가를 기다리고 또는 반환해야하지만, 그렇지 않으면 내 코드는 컴파일되지 않습니다 :

public class MyImplementation: IAuthenticationTokenProvider 
{ 
    public async Task CreateAsync(AuthenticationTokenCreateContext context) 
    { 
     /// do something synchronously. 

     await something here? ?? 
    } 
} 

내 질문은 : 어떻게 비동기 적으로 일을하지 않고이 방법을 구현하는 것이? 나는 몇 가지 해결책 (await를 task.Yield()을 발견, 또는 await Task.Run(() => {})), 아직 나는 완전히 올바른 구현 및 이유 일 것입니다 무슨 이해할 수없는 한 적이

+0

아무 것도 기다리지 않으면 코드가 제대로 컴파일되어야합니다. 실제로 비동기 적이 지 않습니다. 그것은 귀하의 경우에는 IO를 수행하지 않는 기본적으로 빠른 구현 -하지만 그렇지 않으면 당신이 정말로 비동기 적으로 일을해야 괜찮아있을 수도 ... –

+0

만약 내가 이렇게 컴파일하는 동안 경고를 얻을 : "비동기 메서드가 부족합니다 ' '연산자를 기다리고 동기식으로 실행됩니다.' 왜 내가이 경고를 받는가? 왜 중요합니까? –

+0

글쎄, 경고 자체가 말하는 - 비동기 메서드가 있지만 동기식으로 완료됩니다. 당신의 경우에, 그것은 당신이 원하는 것일 수도 있습니다. 'CreateAsync' 메쏘드의 몸체가 무엇을하는지 모른 채로 말하기는 어렵습니다. 항상 빠르다면 괜찮습니다. 그런 코드에 대한 경고는 표시하지 않을 수 있습니다. –

답변

2

그냥 방법을 구현 기다리고 않고 :.

public async Task<Foo> GetFooAsync() 
{ 
    return new Foo(); 
} 

아무 것도 기다리고 있지 않아도 상관 없습니다. 아무것도 기다리지 않는 비동기 메서드가 필요하지 않습니다 (컴파일러에서 아무 것도 기다리고 있지 않다고 경고합니다).

aysnc 메서드의 오버 헤드 (비동기 "상태 시스템"과 관련된 비용이 있습니다.) 바람직하지, 당신은 할 수

public Task<Foo> GetFooAsync() 
{ 
    return Task.FromResult(new Foo()); 
} 
+1

'new asoo' 버전에서'new Foo()'가 예외를 던지면 효과의 차이에 대해 염려 할 필요가 없다. (아마도 마이크로 최적화이기 때문에) 걱정하지 마라. 성공적으로 완료하십시오. 다른 버전에서는 전혀 작업이 반환되지 않습니다. – hvd

+0

문제는 내가 작업 ,하지만 작업과 함께 일하고 있지 않다는 것입니다. 그래서 비동기 무효입니다. 따라서 결과를 생성하는 것이 아닙니다. –

+0

@ClarkKent'Task '는'Task'를 구현하므로'Task.FromResult (0)'만 반환하면'Task'의 (일반이 아닌) 반환 유형을 만족시킬 수 있습니다. 작업의 "가치"는 단지 사용되지 않을 것입니다. – spender

0

내 솔루션은 이미 실행 된 동기 메소드의 결과를 나타내는 Task을 반환하는 것입니다. 그렇게하면 비동기 상태 시스템의 오버 헤드없이 예외가 발생하는 시점에 대한 의미를 비동기 메소드로 유지 관리 할 수 ​​있습니다. 그때를 통해 호출

public static Task AsCompletedTask<T>(this Action<T> func, T arg) 
    { 
     var tcs = new TaskCompletionSource<VoidResult>(); 
     try 
     { 
      func(arg); 
      tcs.SetResult(voidResult); 
     } 
     catch (Exception e) 
     { 
      tcs.SetException(e); 
     }; 

     return tcs.Task; 
    } 

: 재미만큼, 실제로

내가 확장 방법이이 같은 인터페이스에 같은 이유로 이런 짓 BTW

public Task CreateAsync(AuthenticationTokenCreateContext context) 
    { 
     return ((Action<AuthenticationTokenCreateContext>)Create).AsCompletedTask(context); 
    } 

을 나는 싫어 이름. 누구든지 더 좋은 제안을한다면, 나는 모든 귀입니다.