1

I need to delete a file and some other process in the application blocks it. As a workaround I decided to try several times with an interval. Is it correct approach:

Observable.Start(() => File.Delete(path)).Retry(2)
    .Delay(TimeSpan.FromMilliseconds(500)).Wait();
Alex Netkachov
  • 13,172
  • 6
  • 53
  • 85

1 Answers1

8

This won't work the way you want. There are three problems:

  • Delay doesn't work how you think - it delays passing on the events, but the source still runs immediately.
  • You are issuing the Retry before the Delay
  • You need to use Defer to create a factory because Start will only call the embedded function once on evaluation.

Have a look at this answer for more detail on Delay and why DelaySubscription is better: Rx back off and retry.

This answer has a good implementation of a back-off retry: Write an Rx "RetryAfter" extension method

A simple fix for your code could be this, which catches the exception and rethrows it after a delay - but there's no delay if it works:

Observable.Defer(() => Observable.Start(() => File.Delete(path)))
   .Catch((Exception ex) =>
      Observable.Throw<Unit>(ex)
      .DelaySubscription(TimeSpan.FromMilliseconds(500)))
   .Retry(2)
   .Wait();

Do have a look at the second link above for a fuller and better implementation though.

I kept the code above simple to make the point and isn't perfect - it always delays the exception for example.

You really want to have the DelaySubscription on the action and have it's delay time be dynamically calculated depending on the number of retries, which is what the linked implementation will do.

Community
  • 1
  • 1
James World
  • 29,019
  • 9
  • 86
  • 120
  • This looks broken. Shouldn't we be using `Observable.Defer`? `File.Delete` is only being called a single time in this implementation, which means there's no use in retrying since the Exception is memoized. No? – cwharris Apr 11 '14 at 17:40
  • Thanks Christopher. Schoolboy error fixed... :) I think I just reminded someone else of that yesterday as well! Doh! – James World Apr 11 '14 at 19:10
  • But that Catch/throw/delay combo is really clever, though. I'm totally gonna use that. – cwharris Apr 12 '14 at 17:02