2013-07-14 28 views
0

我創建了一個鎖對象包裝器(類),它使用semaphoreSlim(1)作爲我的管理器(類)操作的鎖定機制。
我的經理類包含一個鎖,我發送建設新的包裝類,然後我用這個包裝類鎖(等待我發送建設鎖)等待。並在Dispose上釋放它(封裝類的目的是自動鎖定和釋放,鎖定構造,並在處置後釋放)。既然不能使用異步/地等待着一個構造函數方法在課堂建設後運行異步操作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修飾符,該修飾符將您的方法轉換爲協同例程。

如果沒有這些關鍵字來產生它們提供的相同行爲,你就無法模擬協同例程的創建。