@@ -114,9 +114,7 @@ public void Dispose()
114114 _scheduledExpiration ? . Cancellation . Dispose ( ) ;
115115 }
116116
117- private IDisposable OnScheduledExpirationInvoked (
118- IScheduler scheduler ,
119- Expiration intendedExpiration )
117+ private IDisposable OnScheduledExpirationInvoked ( Expiration intendedExpiration )
120118 {
121119 try
122120 {
@@ -256,9 +254,20 @@ private void FinishSchedulingExpiration(
256254 ScheduledExpiration unfinishedExpiration ,
257255 IScheduler scheduler )
258256 => unfinishedExpiration . Cancellation . Disposable = scheduler . Schedule (
259- state : unfinishedExpiration . Expiration ,
257+ state : (
258+ thisReference : new WeakReference < Subscription > ( this ) ,
259+ expiration : unfinishedExpiration . Expiration ) ,
260260 dueTime : unfinishedExpiration . Expiration . ExpireAt ,
261- action : OnScheduledExpirationInvoked ) ;
261+ action : static ( _ , state ) =>
262+ {
263+ // Most schedulers won't clear scheduled actions upon cancellation, they'll wait until they were supposed to occur.
264+ // A WeakReference here prevents the whole subscription from memory leaking
265+ // Refer to https://github.com/reactivemarbles/DynamicData/issues/1025
266+ if ( state . thisReference . TryGetTarget ( out var @this ) )
267+ @this . OnScheduledExpirationInvoked ( state . expiration ) ;
268+
269+ return Disposable . Empty ;
270+ } ) ;
262271
263272 private void TryPublishCompletion ( )
264273 {
0 commit comments