2013-07-14 2 views
0

관리자 (클래스) 작업을위한 잠금 메커니즘으로 semaphoreSlim (1)을 사용하는 잠금 객체 래퍼 (클래스)를 만들었습니다.
내 관리자 클래스에는 새 래퍼 클래스를 생성 할 때 보내는 잠금이 포함되어 있습니다. 그런 다음이 래퍼 클래스 잠금에 대한 Await을 사용합니다. 실제로이 잠금은 생성시 보냈던 잠금을 기다리고 있습니다. Dispose (래퍼 클래스의 목적은 자동으로 잠금 및 해제하고, 생성시 잠금 및 처분시 해제)입니다. 내가 생성자 메서드에 비동기/await를 사용할 수 없기 때문에클래스 생성 후 비동기 작업 실행 C#

//_syncLock is a class that used as member lock to use in my operations as async lock. 
using (OperationSyncLockWrapper syncLock = new OperationSyncLockWrapper(_syncLock)) 
{ 
    await syncLock.Wait(); //I wish to avoid this line and run it automatically 
    await SomeAsyncOperation(parameter1); 
} 

:

나는 내가 만든 새로운 잠금 랩퍼이 패턴을 사용합니다. 방금 생성 한 새로운 객체를 기다리는 또 다른 방법이 있습니까? 클래스 생성 또는 바로 후에?

답변

6

글쎄, 안타깝게도 오브젝트 구성을 코 루틴으로 나눌 수 없습니다. 따라서 생성자에서는 async을 사용할 수 없습니다.

팩터 리 패턴으로 래퍼 API를 표시 할 수 있습니다.

using (var syncLock = await OperationSyncLockWrapperFactory.GetInstanceAsync(_syncLock)) 
{ 
    await SomeAsyncOperation(parameter1); 
} 

할 수 있습니다 공장 출하 방법 await :

public static class OperationSyncLockWrapperFactory { 

    public static async Task<OperationSyncLockWrapper> GetInstaceAsync(YourSyncLockClass _syncLock) 
    { 
     OperationSyncLockWrapper syncLock = new OperationSyncLockWrapper(_syncLock); 
     await syncLock.Wait(); 

     return syncLock; 
    } 
}  

편집 : 감사 스티븐 제안합니다. 확장 메소드를 사용하면 API를 사용하면 훨씬 더 명확 해집니다.

using (var syncLock = await _syncLock.GetSyncLockWrapperInstanceAsync()) 
{ 
    await SomeAsyncOperation(parameter1); 
} 

그리고 확장 클래스 :

public static class YourSyncLockClassExtensions { 

    public static async Task<OperationSyncLockWrapper> GetSyncLockWrapperInstanceAsync 
                 (this YourSyncLockClass _syncLock) 
    { 
     OperationSyncLockWrapper syncLock = new OperationSyncLockWrapper(_syncLock); 
     await syncLock.Wait(); 

     return syncLock; 
    } 
}  

편집 2 : 귀하의 제안을 바탕으로,이 같은 것 당신이 당신의 라이브러리와 다른 개발자에게 비동기 API를 노출하는 경우, 일반적으로 , await이 라이브러리 내부에있을 때 SynchronizationContext을 캡처하고 싶지는 않습니다. 이는 최상의 방법입니다. 귀하의 경우에도 await은 출고시 방법이므로 SynchronizationContext을 캡처하지 않는 것이 좋습니다. 공장 출하 방법에서

:

await syncLock.Wait().ConfigureAwait(false); 
+0

공장 방법은'_syncLock' 유형에 대한 확장 메서드 인 경우이 훨씬 청소기 될 것이다. –

+0

@StephenCleary : 감사합니다. 귀하의 제안에 따라 업데이트 된 답변 – YK1

+0

시간을 헌정 해 주셔서 감사합니다. 이것은 좋은 해결 방법입니다. – ilansch

0

현재 await으로가는 유일한 길은 해당 키워드와 async 수정자를 메서드 선언에 사용하여 메서드를 공동 루틴으로 변환하는 것입니다.

키워드가없는 공동 루틴 작성을 시뮬레이트하여 동일한 작동을 생성 할 수 없습니다.