2017-10-20 1 views
-2

정말 sync 메소드를 사용하여 클래스 라이브러리를 만들고 싶었 기 때문에 Task.Run을 사용하여 동기화 코드를 실행하는 가짜 비동기 메소드를 구현하지 않으려했습니다.진정한 비동기 메서드를 구현하는 방법은 무엇입니까?

내가 한 가지 방법은이 방법에 있음을 보았다 :

public Task miMethodAsync() 
{ 
    TaskCompletionSource<bool> miTcs = new TaskCompletionSource<bool>(); 
    new Timer(_ => 
     { 
      for (Int64 i = 1; i < 10000000; i++) 
      { 
       //todo my long code 
      } 
      miTcs.SetResult(true); 
     }) 
     .Change(0, Timeout.Infinite); 

    return miTcs.Task; 
} 

이 솔루션은 타이머 내부의 코드를 실행, 나중에 에선 0ms에서 다음 작업을 반환하는 타이머를 사용합니다.

이 솔루션은 새로운 작업을 생성하지 않으므로 스레드 폼 스레드 풀을 차지하지 않으므로 확장 성이 좋습니다. 그러나 타이머를 사용하여 동기화 코드를 실행하는이 솔루션은 우아한 솔루션이 아니므로 정말 비동기 메서드를 구현할 수 있는지 궁금합니다.

이 솔루션은 내 동기화 방법을 가질 수 그냥 이런 식으로 asyn 방법을 구현하기 때문에 :

public Task myMethodAsync() 
{ 
    TaskCompletionSource<bool> miTcs = new TaskCompletionSource<bool>(); 
    new Timer(_ => 
     { 
      myMethodSync(); 
      miTcs.SetResult(true); 
     }) 
     .Change(0, Timeout.Infinite); 

    return miTcs.Task; 
} 

을하지만 주석으로, 나는 그것이 우아한 해결책이 아니라 생각하지만, 정말이 보인다 Task.Run() 메서드 내에서 동기화 코드를 실행할 때와 같은 가짜 비동기 메서드는 아닙니다.

+0

타이머 코드가 동일한 스레드에서 실행되고 (이 스레드는 UI 스레드) 타이머가 오래 실행되면 UI가 여전히 고정됩니다. 만약; 그러나 타이머가 새로운 스레드를 생성합니다. 타이머로 이것을 숨겨서 무엇을 얻고 있습니까? –

+3

이것은 동기화 메서드가 실행되는 동안 스레드를 사용합니다. 그것이 활성 스레드, UI 스레드 또는 스레드 풀 스레드인지 여부는 사용중인 .NET 라이브러리의 'Timer'라는 6 개의 클래스 중 어떤 스레드가'myMethodAsync()'를 호출하는지에 따라 다릅니다. –

+1

동기식 코드에 비해 왜 'async' 래퍼를 만들고 싶습니까? [마지막 질문에서 인용 된 게시물] (https://stackoverflow.com/questions/46845005/is-it-really-a-bad-ide-to-use-threads-in-a-class-library)을 읽었다 고 가정합니다.) 당신은 그것이 나쁜 생각이라는 것을 압니다. 'Task' 리턴 인터페이스를 수행하고 있습니까? 그렇다면'Task.FromResult' 또는'Task.CompletedTask'를 반환하고 클라이언트가 언제 프로세스를 오프로드할지 결정하게하십시오. 더 자세한 내용이 없으면 이전 조언 ([** do not do ** **]) (https://stackoverflow.com/a/32642687/7339946)을 참고하십시오. – JSteward

답변

1

동기 코드를 의사 async 메서드로 랩핑하는 이러한 래퍼는 아무 효과가 없습니다. 권장되는 방법은 이러한 래퍼를 작성하는 것이 아니라 API 사용자가 Task.Run (SyncMethod) 자체를 수행하도록하는 것입니다.

자세한 내용은 article을 확인하십시오.