我创建了一个锁对象包装器(类),它使用semaphoreSlim(1)作为我的经理(类)操作的锁定机制。
我的经理类包含一个锁,我在构造新的包装类时发送,然后我在这个包装类锁上使用Await(实际上等待我在构造时发送它的锁)。并在Dispose上释放它(包装类的目的是自动锁定和释放,锁定构造,并在处置时释放)。
我将此模式用于我构建的新锁包装器:
//_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);
}
因为我不能在构造函数方法中使用async / await。还有另一种方法可以等待我刚创建的新对象 - 在类构造上还是之后?
答案 0 :(得分: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;
}
}
编辑:感谢Stephen提出的建议。同意使用扩展方法,使用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时,通常,当您在库中SynchronizationContext
时,您不想捕获await
- 这也是一种最佳做法。在您的情况下,现在您在工厂方法中await
,您会考虑不要捕获SynchronizationContext
。
在工厂方法中:
await syncLock.Wait().ConfigureAwait(false);
答案 1 :(得分:0)
当前await
的唯一方法是在方法声明中实际使用该关键字以及async
修饰符,这会将您的方法转换为协同例程。
如果不使用这些关键字来生成相同的行为,就无法模拟共同例程的创建。