在类构造C#之后运行异步操作

时间:2013-07-14 07:28:01

标签: c# asynchronous async-await

我创建了一个锁对象包装器(类),它使用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。还有另一种方法可以等待我刚创建的新对象 - 在类构造上还是之后?

2 个答案:

答案 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修饰符,这会将您的方法转换为协同例程。

如果不使用这些关键字来生成相同的行为,就无法模拟共同例程的创建。