【问题标题】:DevForce doesn't always fire Queued Events if they are queued during a call to FireQueuedEvents如果在调用 FireQueuedEvents 期间排队事件,DevForce 并不总是触发排队事件
【发布时间】:2015-06-02 22:54:05
【问题描述】:

我们遇到了以下情况:我们更改了实体的属性,但PropertyChanged 事件没有触发。我们正在将此逻辑作为保存的一部分执行,因此问题似乎是 DevForce 在保存期间对此类事件进行排队的方式。

查看 LoadingBlock.Dispose() 的代码,我看到了:

public void Dispose()
{
    this._entityManager.FireQueuedEvents();
    this._entityManager.IsLoadingEntity = this._wasLoadingEntity;
}

在更改IsLoadingEntity 属性之前,您会触发排队的事件。这意味着在 FireQueuedEvents 期间生成的任何新事件都将被排队(因为IsLoadingEntity 仍然是真的),但排队的事件将永远不会被触发,因为我们已经触发了排队的事件(我们知道)。似乎 DevForce 应该在触发事件之前重置 IsLoadingEntity 标志。我认为这会解决我们的问题。

这里有一些代码可能有助于解释我们的案例。我将使用 Merge 调用而不是 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.

我发现我可以从一个空的实体管理器中执行另一个合并,这将导致之前排队的事件触发。在我们遇到这种情况的一种情况下,这是一个不错的解决方法。但我担心我们可能会在其他地方遇到这个问题,而这种解决方法对我们不起作用。

【问题讨论】:

    标签: c# events devforce


    【解决方案1】:

    你说得对,应该在 Dispose 逻辑的开头清除 IsLoadingEntity 标志,我们将为此打开一个错误报告。

    如果您能够使用 EntityChanging 事件而不是 EntityChanged,这也可能是一种解决方法。更改事件没有排队,因此处理程序的执行会导致 PropertyChanged 事件在 LoadingBlock 被释放之前被处理。

    【讨论】:

    • 我们在EntityChanged 中有大量逻辑,所以我现在很害怕更改它。目前,我们在保存后使用空合并对其进行了破解,这一切正常。但我们期待在正式版本中解决这个问题。谢谢!
    • 是否有任何关于此修复何时可用的估计。我正在调试另一个我认为可能是由这种奇怪的竞争条件引起的问题。我希望能够在应用修复后测试我的用例,因为我希望修复可以用一块石头解决两只鸟。
    • 下一个版本应该在接下来的 2-3 周内。此问题已修复,但假期延迟了发布。
    • 能否早一点发布“测试版”?我真的不需要它“准备好生产”。我只是用它来测试我当前的错误,然后如果它确实修复了它,我可以等待 2-3 周的正式版本。
    • 好的,我可以在周一或周二给你弄一个。
    猜你喜欢
    • 2012-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多