只有执行修改的代码才能知道其批次更改是否完成。
我对我的类似课程所做的工作是提供SuspendNotifications()
和ResumeNotifications()
方法,这些方法以明显的方式调用(即在进行一系列更改前调用暂停,完成时调用恢复)。
它们在内部维护一个计数器,该计数器在SuspendNotifications()中递增,并由ResumeNotifications()递减,如果递减结果为零,则会发出通知。我这样做是因为有时候我会修改一些属性,然后调用另一个修改更多的方法,并且本身会调用暂停/恢复。
(如果简历被称为太多次,我抛出的异常。)
如果多个属性被更改,最后通知不名要更改的属性(因为有不止一个)。我想你可以累积一个已更改的属性列表,并将其作为通知的一部分发布,但这听起来不太有用。
另请注意,线程安全性可能会或可能不会成为您的问题。您可能需要使用锁定和/或Interlocked.Increment()
等。
另一件事是,当然最终需要围绕您的调用try/catch暂停/恢复,以防出现异常。您可以通过编写实现IDisposable的包装类来避免这种情况,并在其Dispose中调用resume。
代码可能是这样的:
public void DoStuff()
{
try
{
_entity.SuspendNotifications();
setProperties();
}
finally
{
_entity.ResumeNotifications();
}
}
private setProperties()
{
_entity.ID = 123454;
_entity.Name = "Name";
_entity.Description = "Desc";
}
[编辑]
如果你要引入一个接口,说ISuspendableNotifications
,你可以写一个IDisposable
包装类把事情简单化。
下面的例子说明了这个概念;使用NotificationSuspender
简化了(实际上删除了)try/catch逻辑。
请注意,class Entity
当然并不实际挂起/恢复或提供任何错误处理;这对读者来说就是众所周知的。 :)
using System;
namespace Demo
{
public interface ISuspendableNotifications
{
void SuspendNotifications();
void ResumeNotifications();
}
public sealed class NotificationSuspender: IDisposable
{
public NotificationSuspender(ISuspendableNotifications suspendableNotifications)
{
_suspendableNotifications = suspendableNotifications;
_suspendableNotifications.SuspendNotifications();
}
public void Dispose()
{
_suspendableNotifications.ResumeNotifications();
}
private readonly ISuspendableNotifications _suspendableNotifications;
}
public sealed class Entity: ISuspendableNotifications
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public void SuspendNotifications() {}
public void ResumeNotifications() {}
}
public static class Program
{
public static void Main(string[] args)
{
Entity entity = new Entity();
using (new NotificationSuspender(entity))
{
entity.Id = 123454;
entity.Name = "Name";
entity.Description = "Desc";
}
}
}
}
很大程度上取决于其他要求,例如听众对单个财产的变化采取行动还是他们总是处理实体,而不管修改的数量和位置如何? – 2013-03-13 13:34:06
为什么不使用标志?如果标志1和2被设置,但3不是...不要做任何事情。当事件触发并设置了标记3时,THEN会处理您要执行的任何代码。 – 2013-03-13 13:36:25
OT: 我意识到我最初的想法与“使用”语句来自log4net实现,其中调用log4net.NDC.Push()以将上下文消息推送到当前线程的上下文中... – ForestC 2013-03-13 15:02:57