gpt4 book ai didi

c# - volatile IEnlistmentNotification 和 TransactionScope.AsyncFlowEnabled = true

转载 作者:行者123 更新时间:2023-11-30 16:09:38 25 4
gpt4 key购买 nike

除了 .NET 4.5.1 之外,TransactionScope 上还有一个新选项可以使用异步流。这允许编写以下客户端代码

using(var txt = new TransactionScope(..., TransactionScopeAsyncFlowOption.Enabled)
{
await sender.SendAsync();
}

到目前为止一切顺利。但是当我需要实现一个不稳定的 IEnlistmentNotification 时,我很难做到这一点。让我们想象以下场景,假设:我的底层基础设施是从下到上完全异步的

public class MessageSender : ISendMessages
{
public async Task SendAsync(TransportMessage message, SendOptions options)
{
await sender.SendAsync(message);
}
}

所以我想要实现的是像这样引入一个可变的 IEnlistmentNotification:

internal class SendResourceManager : IEnlistmentNotification
{
private readonly Func<Task> onCommit;

public SendResourceManager(Func<Task> onCommit)
{
this.onCommit = onCommit;
}

public void Prepare(PreparingEnlistment preparingEnlistment)
{
preparingEnlistment.Prepared();
}

public void Commit(Enlistment enlistment)
{
await this.onCommit();
enlistment.Done();
}

public void Rollback(Enlistment enlistment)
{
enlistment.Done();
}

public void InDoubt(Enlistment enlistment)
{
enlistment.Done();
}
}

和新的发件人

public class MessageSender : ISendMessages
{
public async Task SendAsync(TransportMessage message, SendOptions options)
{
// Dirty: Let's assume Transaction.Current is never null
Transaction.Current.EnlistVolatile(new SendResourceManager(async () => { await sender.SendAsync(message) }));
}
}

注意:当然这段代码不能编译。它需要我声明提交方法异步无效。这太棒了。

所以我的问题是:如何编写可以在内部等待异步操作的登记?

最佳答案

只要 EnlistVolatile 不是一个占用大量 CPU 时间的耗时操作,您就可以在 EnlistVolatile 上使用Task.FromResult :

public static class TranscationExtensions
{
public static Task EnlistVolatileAsync(this Transaction transaction,
IEnlistmentNotification
enlistmentNotification,
EnlistmentOptions enlistmentOptions)
{
return Task.FromResult(transaction.EnlistVolatile
(enlistmentNotification,
enlistmentOptions));
}
}

然后在你的方法中使用它:

public class MessageSender : ISendMessages
{
public Task SendAsync(TransportMessage message, SendOptions options)
{
return Transaction.Current.EnlistVolatileAsync
(new SendResourceManager(async () =>
{ await sender.SendAsync(message) }));
}
}

可以在您的调用堆栈中等待更高的位置:

MessageSender sender = new MessageSender();
await sender.SendAsync(message, options);

关于c# - volatile IEnlistmentNotification 和 TransactionScope.AsyncFlowEnabled = true,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27244154/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com