پیاده سازی مکانیسم سعی مجدد (Retry)
نویسنده: عثمان رحیمی
تاریخ: ۱۳۹۶/۰۹/۱۴ ۲۰:۲۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
public class Mailer
{
public static bool SendEmail()
{
Console.WriteLine("Sending Mail ...");
// simulate error
Random rnd = new Random();
var rndNumber = rnd.Next(1, 10);
if (rndNumber != 3) // *
throw new SmtpFailedRecipientException();
Console.WriteLine("Mail Sent successfully");
return true;
}
} public static class Retry
{
public static void Do(Action action,TimeSpan retryInterval,int maxAttemptCount = 3)
{
Do<object>(() =>
{
action();
return null;
}, retryInterval, maxAttemptCount);
}
public static T Do<T>(Func<T> action,TimeSpan retryInterval,int maxAttemptCount = 3)
{
var exceptions = new List<Exception>();
for (int attempted = 0; attempted < maxAttemptCount; attempted++)
{
try
{
if (attempted > 0)
{
Thread.Sleep(retryInterval);
}
return action();
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
throw new AggregateException(exceptions);
}
} retryInterval= retryInterval.Add(TimeSpan.FromSeconds(10));
در سادهترین حالت، استفاده از Polly همانند زیر است:
var policy = Policy.Handle<SmtpFailedRecipientException>().Retry();
policy.Execute(Mailer.SendEmail); متد Retry، دارای Overloadهای مختلفی است که یکی از آنها مقدار تعداد دفعات تلاش را دریافت میکند؛ همانند:
var policy = Policy.Handle<SmtpFailedRecipientException>().Retry(5);
لازم به ذکر است که باید دقیقا Exception مورد نظر را در بخش Config به کار ببرید. برای نمونه اگر کد فوق را همانند زیر به کار ببرید، در صورتیکه متد ارسال ایمیل با خطایی مواجه شود، هیچ تلاشی برای اجرای مجدد نخواهد کرد:
var policy = Policy.Handle<SqlException>().Retry(5);
برای نمونه میتوان از متد ForEver آن استفاده کرد تا زمانیکه متد مورد نظر Success نشده باشد، سعی در اجرای آن کند:
Policy .Handle<DivideByZeroException>() .RetryForever()