0

DBContexts 是短暂的,每个请求都会创建和销毁。我有许多我想在保存之前和之后执行的任务,我想用某种事件模型来处理这些。我想知道RX是正确的路线。

是否有某种方法可以创建一个单例“集线器”,然后导致我的 DBContext 引发 BeforeChange(SavingChanges 事件)并发布保存(无适用事件)Observables 并将它们“推”到长寿集线器中。

实际上,我想在我的“集线器”单例中执行此操作

    public IObservable<EventPattern<EventArgs>> Saves = new Subject<EventPattern<EventArgs>>();

    public void AttachContext(DbContext context)
    {
        Saves = Observable.FromEventPattern<EventArgs>(((IObjectContextAdapter)context).ObjectContext, "SavingChanges");
    }

但是以这样一种方式,AttachContext 只是将其生成的 observable 提供给现有的 Saves observabe,而不是替换它(及其所有订阅)?

4

1 回答 1

1

是的。使用嵌套的 observable + 合并:

private readonly Subject<IObservable<EventPattern<EventArgs>> _contexts = new Subject<IObservable<EventPattern<EventArgs>>();

private readonly IObservable<EventPattern<EventArgs>> _saves = _contexts.Merge();

public IObservable<EventPattern<EventArgs>> Saves { get { return _saves; } }

public void AttachContext(DbContext context)
{
    _contexts.OnNext(Observable.FromEventPattern<EventArgs>(((IObjectContextAdapter)context).ObjectContext, "SavingChanges"));
}

唯一的问题是,被观察的上下文列表将无限增长,因为Observable.FromEventPattern永远不会完成。所以这实际上是编码的内存泄漏。

如果您知道db 上下文将用于单次保存,那么您可以在.FirstAsync()Observable.FromEventPattern. 这将导致您的主题在从上下文中看到事件后停止观看上下文。

这仍然会遇到一个问题,即可能附加了一个上下文,但它的保存从未执行(由于逻辑、错误或其他原因)。

我知道解决问题的唯一方法是更改AttachContext​​为返回IDisposable调用者在想要分离上下文时必须使用的:

public IDisposable AttachContext(DbContext context)
{
    var detachSignal = new AsyncSubject<Unit>();
    var disposable = Disposable.Create(() =>
    {
        detachSignal.OnNext(Unit.Default);
        detachSignal.OnCompleted();
    });
    var events = Observable.FromEventPattern<EventArgs>(((IObjectContextAdapter)context).ObjectContext, "SavingChanges");

    _contexts.OnNext(events.TakeUntil(detachSignal));
    return disposable;
}
于 2013-07-05T20:30:54.313 回答