Marc'ın cevabı işe yarıyor, ancak benim durumumda, iyi bir kod bloğu miktarına neden oldu (ve bu şekilde yapmayı unutmak kolay), bu yüzden, deseni zorlayan bir soyutlama ile geldim.
public static class RedisExtensions
{
public static async Task TransactAsync(this IDatabase db, Action<RedisCommandQueue> addCommands)
{
var tran = db.CreateTransaction();
var q = new RedisCommandQueue(tran);
addCommands(q);
if (await tran.ExecuteAsync())
await q.CompleteAsync();
}
}
public class RedisCommandQueue
{
private readonly ITransaction _tran;
private readonly IList<Task> _tasks = new List<Task>();
public RedisCommandQueue Enqueue(Func<ITransaction, Task> cmd)
{
_tasks.Add(cmd(_tran));
return this;
}
internal RedisCommandQueue(ITransaction tran) => _tran = tran;
internal Task CompleteAsync() => Task.WhenAll(_tasks);
}
Bir ihtar: Bu herhangi birinin sonucu almak için kolay bir yol sağlamaz İşte
await db.TransactAsync(commands => commands
.Enqueue(tran => tran.SomeCommandAsync(...))
.Enqueue(tran => tran.SomeCommandAsync(...))
.Enqueue(tran => tran.SomeCommandAsync(...)));
uygulama görebilirsiniz: İşte
Kullanmaya nasıl emreder. Benim durumumda (ve OP'ler) o tamam - Ben her zaman bir dizi yazım için işlemleri kullanıyorum. Bu gerçekten benim kod aşağı kesme kesilmiş ve Enqueue
(bir Görev döndürmek için) gerektiren tran
açığa, bu anda o komutları await
olmamalıdır "unutma" daha az olası olduğunu buldum Ben ararım onları.
Henüz hazır bulunamadığım için: burada "sıraya alındı" sayfasına bakın: http://redis.io/topics/transactions –