Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
189 views
in Technique[技术] by (71.8m points)

c# - Use a specific timeout connected to a retrypolicy

I'm creating a retry policy the following way:

var policy = Policy.Handle<Exception>().WaitAndRetryAsync...

How to chail/build a timeout for the retrypolicy above? Policy.TimeoutAsync returns a TimeoutPolicy, hence I'm not able to do something like

var policy = Policy.TimeoutAsync(30).Handle<Exception>().WaitAndRetryAsync....

Does the timeout become a common setting for all my retry policies?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To combine policies, you build each policy separately, then combine them using PolicyWrap.

To build an overall timeout which applies across all retries as a whole (ie across the entire operation):

var overallTimeoutPolicy = Policy.TimeoutAsync(60); 
var waitAndRetryPolicy = Policy
    .Handle<WhateverException>()
    .WaitAndRetryAsync(/* your wait-and-retry specification*/);
var combinedPolicy = overallTimeoutPolicy.WrapAsync(waitAndRetryPolicy);

await combinedPolicy.ExecuteAsync(cancellationToken => ...)

To impose a timeout on each specific try, wrap the retry and timeout policies in the other order:

var timeoutPerTry = Policy.TimeoutAsync(10); 
var waitAndRetryPolicy = Policy
    .Handle<WhateverException>()
    .WaitAndRetryAsync(/* your wait-and-retry specification*/);
var combinedPolicy = waitAndRetryPolicy.WrapAsync(timeoutPerTry);

await combinedPolicy.ExecuteAsync(cancellationToken => ...);

Or even use both kinds of timeout (per-try, per-overall-operation):

var overallTimeout = Policy.TimeoutAsync(60); 
var timeoutPerTry = Policy.TimeoutAsync(10); 
var waitAndRetryPolicy = Policy
    .Handle<WhateverException>()
    .WaitAndRetryAsync(/* your wait-and-retry specification*/);

var combinedPolicy = Policy
    .WrapAsync(overallTimeout, waitAndRetryPolicy, timeoutPerTry); // demonstrates alternative PolicyWrap syntax

await combinedPolicy.ExecuteAsync(cancellationToken => ...);

The PolicyWrap wiki gives full syntax details, and advice on the effects of different orderings, when combining policies within a wrap.


To answer:

Does the timeout become a common setting for all my retry policies?

Policies apply wherever you use them (whether used individually, or as part of a PolicyWrap).

You can thread-safely use any TimeoutPolicy instance you have configured at multiple call sites. So, to apply that timeout as a common setting for all your retry policies, simply include that same TimeoutPolicy instance in the PolicyWrap for each call site. The single TimeoutPolicy instance can safely be wrapped with different retry policy instances, if desired.

If both your wait-and-retry specification, and timeout specification, are common for all call sites, simply make one PolicyWrap instance encompassing both (per above code examples), and re-use that PolicyWrap instance everywhere. Again - thread safe.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...