Created
January 13, 2020 04:53
-
-
Save mohsinonxrm/995664f86a8bbb0c812602d7ad087c91 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.ServiceModel; | |
using System.Threading; | |
public class Retry | |
{ | |
private const int RateLimitExceededErrorCode = -2147015902; | |
private const int TimeLimitExceededErrorCode = -2147015903; | |
private const int ConcurrencyLimitExceededErrorCode = -2147015898; | |
public static TResult Do<TResult>(Func<TResult> func, int maxRetries = 3) | |
{ | |
int retryCount = 0; | |
while (true) | |
{ | |
try | |
{ | |
return func(); | |
} | |
catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) | |
when (IsTransientError(ex)) | |
{ | |
if (++retryCount >= maxRetries) | |
{ | |
throw; | |
} | |
if (ex.Detail.ErrorCode == RateLimitExceededErrorCode) | |
{ | |
// Use Retry-After delay when specified | |
delay = (TimeSpan)ex.Detail.ErrorDetails["Retry-After"]; | |
} | |
else | |
{ | |
// else use exponential backoff delay | |
delay = TimeSpan.FromSeconds(Math.Pow(2, retryCount)); | |
} | |
Thread.Sleep(delay); | |
} | |
} | |
} | |
private static bool IsTransientError(FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) | |
{ | |
// You can add more transient fault codes to retry here | |
if (ex.Detail.ErrorCode == RateLimitExceededErrorCode || | |
ex.Detail.ErrorCode == TimeLimitExceededErrorCode || | |
ex.Detail.ErrorCode == ConcurrencyLimitExceededErrorCode) | |
{ | |
return true; | |
} | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment