只有執行修改的代碼才能知道其批次更改是否完成。
我對我的類似課程所做的工作是提供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