我們遇到了更改我們實體上的屬性但PropertyChanged
事件未觸發的情況。我們正在將此邏輯作爲Save的一部分,因此問題似乎就像DevForce在Save中排隊這樣的事件。如果DevForce在調用FireQueuedEvents期間排隊等候,並不總是觸發排隊事件
看的LoadingBlock.Dispose()的代碼,我看到:
public void Dispose()
{
this._entityManager.FireQueuedEvents();
this._entityManager.IsLoadingEntity = this._wasLoadingEntity;
}
還有就是你火更改IsLoadingEntity
屬性之前排隊的事件中的競爭條件存在。這意味着任何在FireQueuedEvents期間生成的新事件都將排隊(因爲IsLoadingEntity
仍然是真的),但排隊後的事件將永遠不會被解僱,因爲我們已經釋放了排隊的事件(我們知道的)。似乎DevForce應該在觸發事件之前重置IsLoadingEntity標誌。我認爲這將解決我們的問題。
這裏有一些代碼可能有助於解釋我們的情況。我將使用一個合併,而不是調用的SaveChanges的,因爲它更容易在一個單元測試使用方法:
//Create the main Entity Manager and a test entity
var em = new EntityManager();
var entity = new MyEntity {SID = 123};
em.AttachEntity(entity);
//Create a second copy of the entity and another Entity Manager - this is just so
// we can trigger a merge and see the bad behavior
var copy = new MyEntity { SID = 123, MergeCount = 20 };
var em2 = new EntityManager();
em2.AttachEntity(copy);
//This code is a bit contrived but it's similar to what we are doing in our actual app
em.EntityChanged += (sender, args) =>
{
//If it is a MyEntity that changed and it was from a Merge, increment the MergeCount property
var e = args.Entity as MyEntity;
if (e != null && args.Action == EntityAction.ChangeCurrentAndOriginal)
{
e.MergeCount++;
}
};
//Set up a PropertyChanged event handler to see what properties got changed (according to INotifyPropertyChanged)
var propertiesChanged = new List<string>();
entity.PropertyChanged += (sender, args) => { propertiesChanged.Add(args.PropertyName); };
//Merge the copy entity
em2.CacheStateManager.GetCacheState().Merge(em, RestoreStrategy.Normal);
//At this point, the MergeCount property will be 21 - as expected
Assert.AreEqual(21, entity.MergeCount);
//We should have seen a PropertyChanged event for MergeCount since we changed the property (it was 20 and we set it to 21)
Assert.IsTrue(propertiesChanged.Contains("MergeCount"));
//In the debugger, if we look at em._queuedEvents, we'll see some items in there. One of the items is the PropertyChanged event
// for MergeCount. It 'fired' but was queued...and it will be queued forever because the LoadingBlock is long gone.
我發現我可以做其他的合併從空的實體管理器,這將導致先前排隊事件發生。在我們遇到這種情況的情況下,這是一個好的解決方法。但是我擔心我們可能會遇到其他地方遇到這個問題,該解決方法對我們不起作用。
我們在'EntityChanged'中有很多邏輯,所以我現在很害怕改變它。就目前而言,我們在進行保存之後用空的合併方式對其進行了黑客入侵,並且工作正常。但是我們期待這個正式版本能夠得到修復。謝謝! –
是否有任何有關此修復程序何時可用的估計值。我正在調試另一個我認爲可能是由這種奇怪的競爭條件引起的問題。我希望能夠在應用修復程序後測試我的用例,因爲我希望修復能夠一箭雙鵰解決問題。 –
下一個版本應該在未來2-3周。這個問題已經得到解決,但假期延遲了發佈。 –