Return Using 块中间的一个 Func<Task>

Return a Func<Task> middle of Using block

我想 return 一个 using 块的 Func 中间。在用户运行结果 Func 之前,我应该担心处理吗?

示例代码:

private IDbContextTransaction _transaction;

public Func<Task> BeginTransaction()
{
    Task lockDispose = CommitTransaction();
    using (_transaction = _dbContext.Database.BeginTransaction())
    {
        return async() =>
        {
            await lockDispose;
        };
        Task.WaitAll(lockDispose); //This code is unreachable.
    }
}

private async Task CommitTransaction()
{
    _transaction.Commit();
    await Task.CompletedTask;
}

请注意,结果 Func 的执行时间取决于此服务的用户。

我检查了This Question,这不是我的答案。

既然您希望您的用户能够处理调用 BeginTransactionCommitTransaction 之间的连接,那么您唯一能做的就是将处置移出此范围:

private IDbContextTransaction _transaction;

public Func<Task> BeginTransaction()
{
    _transaction = _dbContext.Database.BeginTransaction()
    return CommitTransaction;
}

private async Task CommitTransaction()
{
    _transaction.Commit();
    _transaction.Dispose();
    await Task.CompletedTask;
}

// I advice you implement IDisposable fully, but 
// this will do for the sake of demonstration
public void Dispose()
{
    _transaction?.Dispose();
}

然后在外面的某个地方,您需要按照以下方式做一些事情:

using (var obj = TheWayYouInitializeYourObject())
{
    var commit = obj.BeginTransaction();
    // DO WORK
    await commit();
}

try
{
    var commit = obj.BeginTransaction();
    // DO WORK
    await commit();
}
finally
{
    obj.Dispose();
}

基本上,您的 using 无法跨越用户工作的空白,因此他们必须自己完成。

将必须与一次性用品一起使用的物品也制成一次性用品通常是个好主意。