debugcsharpMinor
General Retry Strategy
Viewed 0 times
strategyretrygeneral
Problem
Let’s say we copy some file using retry strategy (it might be blocked, etc.):
What do you think about names chosen for the following library code identifiers? Would you name them differently?
class Processor
{
public void CopyData() =>
CopyData(Try.Slow);
public void CopyData(Try loop) =>
loop.Execute(() =>
File.Copy(@"c\a.txt", @"c:\b.txt"));
}What do you think about names chosen for the following library code identifiers? Would you name them differently?
public abstract class Try
{
public static Try Repeat(params int[] delays) => new Repeat(delays);
public static readonly Try Never = Repeat();
public static readonly Try Once = Repeat(0);
public static readonly Try Slow = Repeat(0, 500, 1500, 4500, 12000);
public static readonly Try Fast = Repeat(0, 50, 150, 450, 1200);
public abstract void Execute(Action action);
}
class Repeat : Try
{
IReadOnlyList Delays { get; }
public Repeat(params int[] delays)
{
Delays = delays;
}
public override void Execute(Action action)
{
for(int i=0; i< Delays.Count; i++)
try
{
Thread.Sleep(Delays[i]);
action();
return;
}
catch
{
if (i == Delays.Count - 1)
throw;
}
}
}Solution
I think this would be more useful if the user could specify an interval and how many times he wants to retry like:
or if he could specify a count and the increment function:
where the increment could be:
I wouldn't provide such members as
One more thoght. How about specifying the retry strategy via a generic argument:
the
use:
This way the user can easier specify his strategy.
public static Try Repeat(int dalay, int count)
=> new Repeat(Enumerable.Repeat(delay, count));or if he could specify a count and the increment function:
public static Try Repeat(int count, Func increment)
=> new Repeat(Enumerable.Range(1, count + 1).Select(x => increment(x));where the increment could be:
x => x * 20I wouldn't provide such members as
Fast or Slow because they are very subjective and what for you currently is slow might be in my application still too fast.Never does not make any sense ;-) Why should I want to never try to execute something? I might as well not write the code at all if it shouldn't run :-POne more thoght. How about specifying the retry strategy via a generic argument:
class SlowTry : Repeat
{
public SlowTry() : base(0, 500, 1500, 4500, 12000) { }
}the
Try becomes this:public abstract class Try
{
... stays the same
public static void Execute(Action action) where TStrategy : Try, new()
{
new TStrategy().Execute(action);
}
}use:
Try.Execute(() => File.Copy(@"c\a.txt", @"c:\b.txt"));This way the user can easier specify his strategy.
Code Snippets
public static Try Repeat(int dalay, int count)
=> new Repeat(Enumerable.Repeat(delay, count));public static Try Repeat(int count, Func<int, int> increment)
=> new Repeat(Enumerable.Range(1, count + 1).Select(x => increment(x));x => x * 20class SlowTry : Repeat
{
public SlowTry() : base(0, 500, 1500, 4500, 12000) { }
}public abstract class Try
{
... stays the same
public static void Execute<TStrategy>(Action action) where TStrategy : Try, new()
{
new TStrategy().Execute(action);
}
}Context
StackExchange Code Review Q#140166, answer score: 3
Revisions (0)
No revisions yet.