Where is the right place to implement weak and synchronized .NET delegates?
When implementing the weak-reference and/or thread synchronization pattern for delegates, are there guidelines and or anti-patterns as to where the logic should be implemented?
Consider that the class WindowA wants to subscribe to an event on DataB, where DataB is a long-lived instance which is modified on many (non-UI threads).
The options for implementing weak, synchronized events are:
- 开发者_如何学C
Option 1: When WindowA attaches a delegate to the custom event on DataB, the cusom event logic checks SynchronizationContext.Current for the calling thread, and stores this so that later, when the event is raised, the delegate can be invoked via the SynchronizationContext. or:
Option 2: WindowA implements ProxyC, which acts as a target for DataB. Target methods on ProxyC implement synchronization and weak referencing logic, and forwards invocations to methods on WindowA. WindowA is able to be garbage collected, but ProxyC must dettach itself from all events before it can be garbage collected. or:
Option 3: WindowA uses delegate conversion utilities (like those from in SharpObservation) to make the delegates weak and synchronized before attaching them to events on DataB. i.e.:
DataB.PropertyChanged += new PropertyChangedEventHandler(WindowA.HandlePropertyChanged).MakeWeak()
First off... is there any merit to Option 1? While it's a convenient place to implement to weak reference and sync logic, it seems to break the single-responsibility pattern to force a data object to become aware of synchronization and referencing semantics.
Option 2 seems nice and clean. I like it in every way except for the fact that it involves the extra work of creating an extra class to handle the weak referencing. Even so, you get a memory leak unless the proxy knows how to remove the delegates that are targeting it.
Option 3 allows the delegates themselves to carry the responsibility of synchronization and weak referencing, but has the draw-back that the utility methods must be invoked by the code attaching the events. As far as I know, most UI data-binding technologies don't allow you to control how the data binding attaches to events on DataB (hence the alure of option 1).
The BIG question... Is there a one-size-fits-all pattern to be had here? Is there a single, better-than-all-others pattern?
精彩评论