Skip to content

Commit 122af7f

Browse files
committed
Fixed documentation of PostSharp.Samples.WeakEvent.
1 parent 6a33c34 commit 122af7f

File tree

1 file changed

+11
-9
lines changed
  • Framework/PostSharp.Samples.WeakEvent

1 file changed

+11
-9
lines changed

Framework/PostSharp.Samples.WeakEvent/README.md

+11-9
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,21 @@ Therefore, the weak event does not prevent the listener objects to be garbage co
66
Event handlers are often source of memory leaks in .NET. The reason is that the delegates registered as event handlers store a strong reference to the listener objects.
77
The event source indirectly holds a strong reference to all listener objects.
88

9-
Implementing the weak event pattern requires cooperation of the event source and the listener object. If the exposing object only stores weak references to the delegates,
10-
the delegates are immediately collected even while the consumer object is still alive. To prevent immediate garbage collection of delegates,
11-
the consumer must hold strong references to all delegates passed to the weak events.
9+
In the weak event pattern, the event source does not hold a strong reference to the event listener. Instead, it stores a WeakReference
10+
to the delegate. However, it is still necessary to ensure that there is at least one strong reference to the delegate, otherwise
11+
it would get collected immediately upon the next GC cycle. In this example, we use a WeakConditionalTable to establish a strong reference
12+
between the target of the delegate and the delegate itself. This makes sure that the delegate is alive until the delegate target instance
13+
is alive.
1214

13-
The pattern is implemented by the following artefacts:
15+
Note that this approach does not work with some anonymous methods or lambda expressions because they are compiled as
16+
closure classes. Nothing keeps alive the closure class instance itself. This case is not covered by this example.
1417

15-
* The `[WeakEvent]` aspect can be applied to any event. The `[WeakEvent]` aspect is based on `EventInterceptionAspect` and implements the `IInstanceScopedAspect` interface to store instance-scoped data.
16-
* The `[WeakEventClient]` aspect can be applied to any consumer of a weak event. The `[WeakEventClient]` aspect automatically implements the `IWeakEventClient` interface. The `[WeakEventClient]` aspect demonstrates the following features: `InstanceLevelAspect`, `IntroduceInterface`.
17-
* The `WeakEventValidation` constraint is attached to the `WeakEvent` aspect. It validates, at build time, that clients of weak events are enhanced with the `[WeakEventClient]` aspect or manually implement the `IWeakEventClient` interface.
18-
Additionally to this build-time validation, the `[WeakEvent]` aspect throws an exception if the consumer class does not have the `[WeakEventClient]` aspect or does not manually implement the `IWeakEventClient` interface.
18+
The `[WeakEvent]` aspect is based on `EventInterceptionAspect` class. It implements the `IInstanceScopedAspect`
19+
interface because the aspect needs to store the list of handlers for each instance of the event.
1920

20-
To allow an event to store strong references when the client does not implement the `IWeakEventClient` interface, use the code `[WeakEvent(AllowStrongReferences=true)]`.
2121

2222
## Limitations
2323

2424
This example has not been sufficiently tested for production use.
25+
This example assumes that the delegate target instance is kept alive, therefore it does not work with anonymous methods
26+
and lambda expressions that use a closure class.

0 commit comments

Comments
 (0)