为集合中的多个对象创建使用块
Create using blocks for multiple objects in collection
给定以下代码:
using (payment.GetModifyLock())
{
foreach (var paymentItem in paymentItems)
{
using (paymentItem.GetModifyLock())
{
}
}
DoAction();
}
我想修改此代码,以便 DoAction
在所有使用块(不仅仅是一个)内完成。如果集合包含两个项目,我希望它以这种方式运行:
using(payment.GetModifyLock())
using(paymentItem1.GetModifyLock())
using(paymentItem2.GetModifyLock())
{
DoAction();
}
这可能吗?
我想我已经使用这段代码解决了这个问题:
using (payment.GetModifyLock())
{
var locks = new List<DistributedLock>();
try
{
foreach (var paymentItem in paymentItems)
{
locks.Add(paymentItem.GetModifyLock());
}
// Do action
}
finally
{
foreach (var locker in locks)
{
locker.Dispose(); ;
}
}
}
如果您想创建一个可重复使用的版本,您可以将功能包装到一个 IDisposable 助手中 class。这很天真,不推荐用于生产代码,但它是一个简单、可重用的抽象。
public class NestedLocker : IDisposable
{
private readonly IDisposable _parentLocker;
private readonly Queue<IDisposable> _childLockers = new Queue<IDisposable>();
public NestedLocker(Func<IDisposable> parentLocker,
IEnumerable<Func<IDisposable>> childLockers)
{
_parentLocker = parentLocker();
foreach (var childLocker in childLockers)
{
_childLockers.Enqueue(childLocker());
}
}
public void Dispose()
{
foreach (var childLocker in _childLockers)
{
childLocker.Dispose();
}
_parentLocker.Dispose();
}
}
您可以使用以下方法对其进行测试:
void Main()
{
Func<IDisposable> parentLocker = () => new ParentLocker();
List<Func<IDisposable>> childLockers =
new List<Func<IDisposable>> { () => new ChildLocker(), () => new ChildLocker() };
using (new NestedLocker(parentLocker, childLockers))
{
Console.WriteLine("action");
}
}
public class ParentLocker : IDisposable
{
public ParentLocker()
{
Console.WriteLine("Parent locker created");
}
public void Dispose()
{
Console.WriteLine("Parent locker disposed");
}
}
public class ChildLocker : IDisposable
{
public ChildLocker()
{
Console.WriteLine("Child locker created");
}
public void Dispose()
{
Console.WriteLine("Child locker disposed");
}
}
输出:
Parent locker created
Child locker created
Child locker created
action
Child locker disposed
Child locker disposed
Parent locker disposed
给定以下代码:
using (payment.GetModifyLock())
{
foreach (var paymentItem in paymentItems)
{
using (paymentItem.GetModifyLock())
{
}
}
DoAction();
}
我想修改此代码,以便 DoAction
在所有使用块(不仅仅是一个)内完成。如果集合包含两个项目,我希望它以这种方式运行:
using(payment.GetModifyLock())
using(paymentItem1.GetModifyLock())
using(paymentItem2.GetModifyLock())
{
DoAction();
}
这可能吗?
我想我已经使用这段代码解决了这个问题:
using (payment.GetModifyLock())
{
var locks = new List<DistributedLock>();
try
{
foreach (var paymentItem in paymentItems)
{
locks.Add(paymentItem.GetModifyLock());
}
// Do action
}
finally
{
foreach (var locker in locks)
{
locker.Dispose(); ;
}
}
}
如果您想创建一个可重复使用的版本,您可以将功能包装到一个 IDisposable 助手中 class。这很天真,不推荐用于生产代码,但它是一个简单、可重用的抽象。
public class NestedLocker : IDisposable
{
private readonly IDisposable _parentLocker;
private readonly Queue<IDisposable> _childLockers = new Queue<IDisposable>();
public NestedLocker(Func<IDisposable> parentLocker,
IEnumerable<Func<IDisposable>> childLockers)
{
_parentLocker = parentLocker();
foreach (var childLocker in childLockers)
{
_childLockers.Enqueue(childLocker());
}
}
public void Dispose()
{
foreach (var childLocker in _childLockers)
{
childLocker.Dispose();
}
_parentLocker.Dispose();
}
}
您可以使用以下方法对其进行测试:
void Main()
{
Func<IDisposable> parentLocker = () => new ParentLocker();
List<Func<IDisposable>> childLockers =
new List<Func<IDisposable>> { () => new ChildLocker(), () => new ChildLocker() };
using (new NestedLocker(parentLocker, childLockers))
{
Console.WriteLine("action");
}
}
public class ParentLocker : IDisposable
{
public ParentLocker()
{
Console.WriteLine("Parent locker created");
}
public void Dispose()
{
Console.WriteLine("Parent locker disposed");
}
}
public class ChildLocker : IDisposable
{
public ChildLocker()
{
Console.WriteLine("Child locker created");
}
public void Dispose()
{
Console.WriteLine("Child locker disposed");
}
}
输出:
Parent locker created
Child locker created
Child locker created
action
Child locker disposed
Child locker disposed
Parent locker disposed