|
|
|
|
namespace Polly8Study.Test
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Polly8<79><38>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|
|
|
|
/// <20>ؼ<EFBFBD><D8BC><EFBFBD>
|
|
|
|
|
/// CancellationToken<65><6E>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Dz<EFBFBD><C7B2><EFBFBD>ʹ<EFBFBD>õ<EFBFBD>
|
|
|
|
|
/// <20><><EFBFBD><EFBFBD>֮ǰ<D6AE>汾<EFBFBD>е<EFBFBD><D0B5>ֹ۳<D6B9>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>۳<EFBFBD>ʱò<CAB1><C3B2>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class Polly8TimeoutStrategyTest
|
|
|
|
|
{
|
|
|
|
|
private readonly ITestOutputHelper _output;
|
|
|
|
|
|
|
|
|
|
public Polly8TimeoutStrategyTest(ITestOutputHelper testOutput)
|
|
|
|
|
{
|
|
|
|
|
_output = testOutput;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void TimeoutStrategyOptions_Test()
|
|
|
|
|
{
|
|
|
|
|
//ֱ<><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
new ResiliencePipelineBuilder()
|
|
|
|
|
.AddTimeout(TimeSpan.FromMilliseconds(100))
|
|
|
|
|
.Build();
|
|
|
|
|
|
|
|
|
|
//Ĭ<><C4AC>ֵ
|
|
|
|
|
var defaultOption = new TimeoutStrategyOptions();
|
|
|
|
|
|
|
|
|
|
//ȫ<><C8AB><EFBFBD><EFBFBD>
|
|
|
|
|
TimeoutStrategyOptions timeoutOption = new TimeoutStrategyOptions
|
|
|
|
|
{
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>Ψһ<CEA8><D2BB>ʶ<EFBFBD><CAB6><EFBFBD>ض<EFBFBD><D8B6><EFBFBD><EFBFBD>Ե<EFBFBD><D4B5>ض<EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɸ<EFBFBD><C9B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>ң<EFBFBD><D2A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
Name = "timeout",
|
|
|
|
|
|
|
|
|
|
//<2F>̶<EFBFBD><CCB6><EFBFBD>ʱʱ<CAB1><CAB1>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TimeoutGenerator<6F><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч)
|
|
|
|
|
Timeout = TimeSpan.FromSeconds(2),
|
|
|
|
|
|
|
|
|
|
//<2F><>̬<EFBFBD><CCAC>ʱʱ<CAB1><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//TimeoutGenerator = arg =>
|
|
|
|
|
//{
|
|
|
|
|
// var ts = TimeSpan.FromSeconds(Math.Pow(2, 1));
|
|
|
|
|
|
|
|
|
|
// return ValueTask.FromResult(ts);
|
|
|
|
|
//},
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱʱ<CAB1><CAB1><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD>ʱί<CAB1><CEAF>
|
|
|
|
|
OnTimeout = (args) =>
|
|
|
|
|
{
|
|
|
|
|
var key = args.Context.OperationKey;
|
|
|
|
|
_output.WriteLine("OnTimeout");
|
|
|
|
|
return ValueTask.CompletedTask;
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//ʹ<><CAB9>
|
|
|
|
|
ResiliencePipeline pipeline = new ResiliencePipelineBuilder()
|
|
|
|
|
.AddTimeout(timeoutOption)
|
|
|
|
|
.Build();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <20>ǿ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F1A3BABA>Գ<EFBFBD>ʱ
|
|
|
|
|
/// ͬ<><CDAC>ִ<EFBFBD><D6B4>
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void No_CancellationToken_Test()
|
|
|
|
|
{
|
|
|
|
|
ResiliencePipeline pipeline = new ResiliencePipelineBuilder()
|
|
|
|
|
.AddTimeout(TimeSpan.FromSeconds(1))
|
|
|
|
|
.Build();
|
|
|
|
|
|
|
|
|
|
//<2F>ⲿtcs<63><73>ʡ<EFBFBD><CAA1>
|
|
|
|
|
var tcs = new CancellationTokenSource();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
pipeline.Execute
|
|
|
|
|
(
|
|
|
|
|
//<2F>˴<EFBFBD><CBB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F1A3ACB7><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ϊ(һֱ<D2BB>ȴ<EFBFBD>)
|
|
|
|
|
callback: (CancellationToken innerToken) =>
|
|
|
|
|
{
|
|
|
|
|
//<2F><>Ȼ<EFBFBD>ӿں<D3BF>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊû<CEAA><C3BB>ʹ<EFBFBD>á<EFBFBD><C3A1><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD>ġ<EFBFBD> Send<6E><64><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD>ԣ<EFBFBD><D4A3><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4>ӿ<EFBFBD><D3BF><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>
|
|
|
|
|
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "http://localhost:44344/api/Timeout/Slow");
|
|
|
|
|
|
|
|
|
|
//<2F>ؼ<EFBFBD><D8BC><EFBFBD>Send<6E><64><EFBFBD><EFBFBD> û<>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> cancellationToken
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻҪ<D6BB>ǿ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
HttpResponseMessage response = new HttpClient().Send(requestMessage);
|
|
|
|
|
if (response.IsSuccessStatusCode == false)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ,<2C><>Ӧ<EFBFBD>룺{response.StatusCode}");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var stream = response.Content.ReadAsStream();
|
|
|
|
|
var bs = new byte[stream.Length];
|
|
|
|
|
stream.Read(bs, 0, (int)stream.Length);
|
|
|
|
|
|
|
|
|
|
var text = System.Text.UTF8Encoding.UTF8.GetString(bs);
|
|
|
|
|
|
|
|
|
|
_output.WriteLine($"<22><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>:{text}");
|
|
|
|
|
|
|
|
|
|
_output.WriteLine("<22><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|
|
|
|
},
|
|
|
|
|
cancellationToken: tcs.Token
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
catch (OperationCanceledException ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"<22><><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
catch (TimeoutRejectedException ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"<22><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"API<50><49><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3>{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
tcs.TryReset();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><>ʱ
|
|
|
|
|
/// ͬ<><CDAC>ִ<EFBFBD><D6B4>
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Has_CancellationToken_Timeout_Test()
|
|
|
|
|
{
|
|
|
|
|
TimeoutStrategyOptions timeoutOption = new TimeoutStrategyOptions
|
|
|
|
|
{
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>Ψһ<CEA8><D2BB>ʶ<EFBFBD><CAB6><EFBFBD>ض<EFBFBD><D8B6><EFBFBD><EFBFBD>Ե<EFBFBD><D4B5>ض<EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɸ<EFBFBD><C9B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>ң<EFBFBD><D2A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
Name = "timeout",
|
|
|
|
|
|
|
|
|
|
//<2F>̶<EFBFBD><CCB6><EFBFBD>ʱʱ<CAB1><CAB1>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TimeoutGenerator<6F><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч)
|
|
|
|
|
Timeout = TimeSpan.FromSeconds(1),
|
|
|
|
|
|
|
|
|
|
//<2F><>̬<EFBFBD><CCAC>ʱʱ<CAB1><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//TimeoutGenerator = arg =>
|
|
|
|
|
//{
|
|
|
|
|
// var ts = TimeSpan.FromSeconds(Math.Pow(2, 1));
|
|
|
|
|
|
|
|
|
|
// return ValueTask.FromResult(ts);
|
|
|
|
|
//},
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱʱ<CAB1><CAB1><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD>ʱί<CAB1><CEAF>
|
|
|
|
|
OnTimeout = (args) =>
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine("OnTimeout <20><>ʱί<CAB1><CEAF>ִ<EFBFBD><D6B4>");
|
|
|
|
|
return ValueTask.CompletedTask;
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ResiliencePipeline pipeline = new ResiliencePipelineBuilder()
|
|
|
|
|
.AddTimeout(timeoutOption)
|
|
|
|
|
.Build();
|
|
|
|
|
|
|
|
|
|
var tcs = new CancellationTokenSource();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
pipeline.Execute
|
|
|
|
|
(
|
|
|
|
|
//<2F>˴<EFBFBD><CBB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F1A3ACB7><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ϊ(һֱ<D2BB>ȴ<EFBFBD>)
|
|
|
|
|
callback: (innerToken) =>
|
|
|
|
|
{
|
|
|
|
|
HttpRequestMessage r = new HttpRequestMessage(HttpMethod.Get, "http://localhost:44344/api/Timeout/Slow");
|
|
|
|
|
var response = new HttpClient().Send(r, innerToken);
|
|
|
|
|
if (response.IsSuccessStatusCode == false)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var stream = response.Content.ReadAsStream();
|
|
|
|
|
var bs = new byte[stream.Length];
|
|
|
|
|
stream.Read(bs, 0, (int)stream.Length);
|
|
|
|
|
|
|
|
|
|
var text = System.Text.UTF8Encoding.UTF8.GetString(bs);
|
|
|
|
|
|
|
|
|
|
_output.WriteLine($"<22><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>:{text}");
|
|
|
|
|
_output.WriteLine("<22><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|
|
|
|
},
|
|
|
|
|
cancellationToken: tcs.Token
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
catch (OperationCanceledException ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"<22><><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
catch (TimeoutRejectedException ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"<22><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"API<50><49><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3>{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
tcs.TryReset();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><><EFBFBD><EFBFBD>ʱ
|
|
|
|
|
/// ͬ<><CDAC>ִ<EFBFBD><D6B4>
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public void Has_CancellationToken_NotTimeout_Test()
|
|
|
|
|
{
|
|
|
|
|
TimeoutStrategyOptions timeoutOption = new TimeoutStrategyOptions
|
|
|
|
|
{
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>Ψһ<CEA8><D2BB>ʶ<EFBFBD><CAB6><EFBFBD>ض<EFBFBD><D8B6><EFBFBD><EFBFBD>Ե<EFBFBD><D4B5>ض<EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɸ<EFBFBD><C9B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>ң<EFBFBD><D2A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
Name = "timeout",
|
|
|
|
|
|
|
|
|
|
//<2F>̶<EFBFBD><CCB6><EFBFBD>ʱʱ<CAB1><CAB1>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TimeoutGenerator<6F><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч)
|
|
|
|
|
Timeout = TimeSpan.FromSeconds(5),
|
|
|
|
|
|
|
|
|
|
//<2F><>̬<EFBFBD><CCAC>ʱʱ<CAB1><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//TimeoutGenerator = arg =>
|
|
|
|
|
//{
|
|
|
|
|
// var ts = TimeSpan.FromSeconds(Math.Pow(2, 1));
|
|
|
|
|
|
|
|
|
|
// return ValueTask.FromResult(ts);
|
|
|
|
|
//},
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱʱ<CAB1><CAB1><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD>ʱί<CAB1><CEAF>
|
|
|
|
|
OnTimeout = (args) =>
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("OnTimeout <20><>ʱί<CAB1><CEAF>ִ<EFBFBD><D6B4>");
|
|
|
|
|
return ValueTask.CompletedTask;
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ResiliencePipeline pipeline = new ResiliencePipelineBuilder()
|
|
|
|
|
.AddTimeout(timeoutOption)
|
|
|
|
|
.Build();
|
|
|
|
|
|
|
|
|
|
var tcs = new CancellationTokenSource();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
pipeline.Execute
|
|
|
|
|
(
|
|
|
|
|
//<2F>˴<EFBFBD><CBB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F1A3ACB7><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ϊ(һֱ<D2BB>ȴ<EFBFBD>)
|
|
|
|
|
callback: (innerToken) =>
|
|
|
|
|
{
|
|
|
|
|
HttpRequestMessage r = new HttpRequestMessage(HttpMethod.Get, "http://localhost:44344/api/Timeout/Slow");
|
|
|
|
|
var response = new HttpClient().Send(r, innerToken);
|
|
|
|
|
if (response.IsSuccessStatusCode == false)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var stream = response.Content.ReadAsStream();
|
|
|
|
|
var bs = new byte[stream.Length];
|
|
|
|
|
stream.Read(bs, 0, (int)stream.Length);
|
|
|
|
|
|
|
|
|
|
var text = System.Text.UTF8Encoding.UTF8.GetString(bs);
|
|
|
|
|
|
|
|
|
|
_output.WriteLine($"<22><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>:{text}");
|
|
|
|
|
_output.WriteLine("<22><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|
|
|
|
},
|
|
|
|
|
cancellationToken: tcs.Token
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
catch (OperationCanceledException ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"<22><><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
catch (TimeoutRejectedException ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"<22><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"API<50><49><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3>{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
tcs.TryReset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <20><><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><><EFBFBD>Գ<EFBFBD>ʱ
|
|
|
|
|
/// <20>첽ִ<ECB2BD><D6B4>
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Fact]
|
|
|
|
|
public async void No_CancellationToken_ExecuteAsync_Test()
|
|
|
|
|
{
|
|
|
|
|
TimeoutStrategyOptions timeoutOption = new TimeoutStrategyOptions
|
|
|
|
|
{
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>Ψһ<CEA8><D2BB>ʶ<EFBFBD><CAB6><EFBFBD>ض<EFBFBD><D8B6><EFBFBD><EFBFBD>Ե<EFBFBD><D4B5>ض<EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɸ<EFBFBD><C9B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>ң<EFBFBD><D2A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
Name = "timeout",
|
|
|
|
|
|
|
|
|
|
//<2F>̶<EFBFBD><CCB6><EFBFBD>ʱʱ<CAB1><CAB1>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TimeoutGenerator<6F><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч)
|
|
|
|
|
Timeout = TimeSpan.FromSeconds(1),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱʱ<CAB1><CAB1><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD>ʱί<CAB1><CEAF>
|
|
|
|
|
OnTimeout = (args) =>
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine("OnTimeout <20><>ʱί<CAB1><CEAF>ִ<EFBFBD><D6B4>");
|
|
|
|
|
return ValueTask.CompletedTask;
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ResiliencePipeline pipeline = new ResiliencePipelineBuilder()
|
|
|
|
|
.AddTimeout(timeoutOption)
|
|
|
|
|
.Build();
|
|
|
|
|
|
|
|
|
|
var tcs = new CancellationTokenSource();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await pipeline.ExecuteAsync
|
|
|
|
|
(
|
|
|
|
|
//<2F>˴<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F1A3ACBA>Գ<EFBFBD>ʱ(<28><>һֱ<D2BB>ȴ<EFBFBD>)
|
|
|
|
|
callback: async (innerToken) =>
|
|
|
|
|
{
|
|
|
|
|
//<2F><><EFBFBD>ɴ<EFBFBD>Լ<EFBFBD><D4BC>2<EFBFBD><32><EFBFBD>࣬<EFBFBD><E0A3AC><EFBFBD><EFBFBD><EFBFBD>dz<EFBFBD>ʱ<EFBFBD><CAB1>1<EFBFBD><31><EFBFBD><EFBFBD>
|
|
|
|
|
await Task.Delay (1000*3);
|
|
|
|
|
_output.WriteLine("<22><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|
|
|
|
},
|
|
|
|
|
cancellationToken: tcs.Token
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
catch (OperationCanceledException ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"<22><><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
catch (TimeoutRejectedException ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"<22><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"API<50><49><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3>{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
tcs.TryReset();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><>ʱ
|
|
|
|
|
/// <20>첽ִ<ECB2BD><D6B4>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[Fact]
|
|
|
|
|
public async Task Has_CancellationToken_ExecuteAsync_Timeout_Test()
|
|
|
|
|
{
|
|
|
|
|
var pipeline = new ResiliencePipelineBuilder()
|
|
|
|
|
.AddTimeout(TimeSpan.FromSeconds(1))
|
|
|
|
|
.Build();
|
|
|
|
|
|
|
|
|
|
await Assert.ThrowsAnyAsync<Exception>(async () =>
|
|
|
|
|
{
|
|
|
|
|
var cts = new CancellationTokenSource();
|
|
|
|
|
await pipeline.ExecuteAsync
|
|
|
|
|
(
|
|
|
|
|
callback: async (innerToken) =>
|
|
|
|
|
{
|
|
|
|
|
//<2F><><EFBFBD>ɴ<EFBFBD>Լ<EFBFBD>dz<EFBFBD>ʱ<EFBFBD><CAB1>1<EFBFBD><31><EFBFBD>࣬<EFBFBD><E0A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD>
|
|
|
|
|
await Task.Delay(1000 * 3, innerToken);
|
|
|
|
|
_output.WriteLine("<22><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|
|
|
|
},
|
|
|
|
|
cancellationToken: cts.Token
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><><EFBFBD><EFBFBD>ʱ
|
|
|
|
|
/// <20>첽ִ<ECB2BD><D6B4>
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[Fact]
|
|
|
|
|
public async Task Has_CancellationToken_ExecuteAsync_NoTimeout_Test()
|
|
|
|
|
{
|
|
|
|
|
var pipeline = new ResiliencePipelineBuilder()
|
|
|
|
|
.AddTimeout(TimeSpan.FromSeconds(3))
|
|
|
|
|
.Build();
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var cts = new CancellationTokenSource();
|
|
|
|
|
await pipeline.ExecuteAsync
|
|
|
|
|
(
|
|
|
|
|
callback: async (innerToken) =>
|
|
|
|
|
{
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>ɴ<EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>1<EFBFBD><31>
|
|
|
|
|
await Task.Delay(1000, innerToken);
|
|
|
|
|
_output.WriteLine("<22><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|
|
|
|
},
|
|
|
|
|
cancellationToken: cts.Token
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine(ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <summary>
|
|
|
|
|
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<3A><>ʱ
|
|
|
|
|
/// <20>첽ִ<ECB2BD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Token
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[Fact]
|
|
|
|
|
public async Task Has_OuterCancellationToken_ExecuteAsync_Timeout_Test()
|
|
|
|
|
{
|
|
|
|
|
var pipeline = new ResiliencePipelineBuilder()
|
|
|
|
|
.AddTimeout(TimeSpan.FromSeconds(1))
|
|
|
|
|
.Build();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await Assert.ThrowsAnyAsync<Exception>(async () =>
|
|
|
|
|
{
|
|
|
|
|
await pipeline.ExecuteAsync
|
|
|
|
|
(
|
|
|
|
|
callback: async (innerToken) =>
|
|
|
|
|
{
|
|
|
|
|
//<2F><><EFBFBD>ɴ<EFBFBD>Լ<EFBFBD>dz<EFBFBD>ʱ<EFBFBD><CAB1>1<EFBFBD><31><EFBFBD>࣬<EFBFBD><E0A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD>
|
|
|
|
|
await Task.Delay(1000 * 3, innerToken);
|
|
|
|
|
_output.WriteLine("<22><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
public void SyncWithCancellationToken_Test()
|
|
|
|
|
{
|
|
|
|
|
ResiliencePipeline pipeline = new ResiliencePipelineBuilder()
|
|
|
|
|
.AddTimeout(TimeSpan.FromSeconds(3))
|
|
|
|
|
.Build();
|
|
|
|
|
|
|
|
|
|
var tcs = new CancellationTokenSource();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
pipeline.Execute
|
|
|
|
|
(
|
|
|
|
|
//<2F>˴<EFBFBD><CBB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F1A3ACB7><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ϊ(һֱ<D2BB>ȴ<EFBFBD>)
|
|
|
|
|
callback: SyncWithCancellationToken,
|
|
|
|
|
cancellationToken: tcs.Token
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
catch (OperationCanceledException ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"<22><><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
catch (TimeoutRejectedException ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"<22><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣:{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_output.WriteLine($"API<50><49><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3>{ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
tcs.TryReset();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// ʹ<><CAB9>CancellationToken<65><6E>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void SyncWithCancellationToken(CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
Thread thread = new Thread((token) =>
|
|
|
|
|
{
|
|
|
|
|
int max = 500;
|
|
|
|
|
while (max > 0)
|
|
|
|
|
{
|
|
|
|
|
if (cancellationToken.IsCancellationRequested)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
max -= 1;
|
|
|
|
|
Thread.Sleep(10);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
thread.Start();
|
|
|
|
|
thread.Join();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|