我正在使用Weak Events in .Net, the easy way中的代碼來處理對可觀察集合的監視更改。該代碼幾個月以來一直沒有任何問題。我最近更新到一臺新電腦。在完成所有設置並從存儲庫中取出代碼後,我遇到了一個奇怪的問題。代碼不再有效!在舊計算機上工作的ReactiveExtension現在失敗了
這裏是我的代碼的相關部分,這一切都發生在構造函數中:
public class PurchaseOrderReceipt : BaseEntity
{
/// <summary>
/// Initializes a new instance of the <see cref="PurchaseOrderReceipt" /> class.
/// </summary>
public PurchaseOrderReceipt()
{
this.ReceiptItems = new ObservableCollection<PurchaseOrderItemReceipt>();
this.DateReceived = DateTime.Now;
this.ReceiptItems.ObserveCollectionChanged()
.SubscribeWeakly(this, (target, eventArgs) => target.ReceiptItemsChanged());
}
拋出異常與以下錯誤消息SubscribeWeakly行:的ArgumentException:onNext必須指向一個靜態方法,否則訂閱仍然會對目標有強烈的參考
我可以通過創建PurchaseOrderReceipt實例來重新創建LinqPad中的問題。
如果我在LinqPad中寫了一個簡單的類來反映PurchaseOrderReceipt類中的設置,它仍然有效。
LinqPad代碼:
void Main()
{
var x = new Test();
x.ReceiptItems.Add(new PurchaseOrderItemReceipt());
}
public class Test:BaseEntity
{
public ObservableCollection<PurchaseOrderItemReceipt> ReceiptItems {get; set;}
public Test()
{
this.ReceiptItems = new ObservableCollection<PurchaseOrderItemReceipt>();
this.ReceiptItems.ObserveCollectionChanged().SubscribeWeakly(this,(target, eventargs) => target.TestChanged());
}
private void TestChanged()
{
"Changed!".Dump();
}
}
改變了!打印在結果窗口中。
以下是頂部鏈接的CustomReactiveExtension類。
public static class CustomReactiveExtension
{
public static IObservable<EventPattern<NotifyCollectionChangedEventArgs>> ObserveCollectionChanged(this INotifyCollectionChanged collection)
{
return Observable.FromEventPattern<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
handler => (sender, e) => handler(sender, e),
handler => collection.CollectionChanged += handler,
handler => collection.CollectionChanged -= handler);
}
public static IDisposable SubscribeWeakly<T, TTarget>(this IObservable<T> observable, TTarget target, Action<TTarget, T> onNext) where TTarget : class
{
var reference = new WeakReference(target);
if (onNext.Target != null)
{
throw new ArgumentException("onNext must refer to a static method, or else the subscription will still hold a strong reference to target");
}
IDisposable subscription = null;
subscription = observable.Subscribe(item =>
{
var currentTarget = reference.Target as TTarget;
if (currentTarget != null)
{
onNext(currentTarget, item);
}
else
{
subscription.Dispose();
}
});
return subscription;
}
}
任何想法?
工作就像一個魅力!謝謝! –