mirror of https://github.com/abpframework/abp.git
committed by
GitHub
9 changed files with 166 additions and 9 deletions
@ -0,0 +1,14 @@ |
|||
using System.Threading; |
|||
|
|||
namespace Volo.Abp.Threading |
|||
{ |
|||
public class CancellationTokenOverride |
|||
{ |
|||
public CancellationToken CancellationToken { get; } |
|||
|
|||
public CancellationTokenOverride(CancellationToken cancellationToken) |
|||
{ |
|||
CancellationToken = cancellationToken; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System; |
|||
using System.Threading; |
|||
|
|||
namespace Volo.Abp.Threading |
|||
{ |
|||
public abstract class CancellationTokenProviderBase : ICancellationTokenProvider |
|||
{ |
|||
public const string CancellationTokenOverrideContextKey = "Volo.Abp.Threading.CancellationToken.Override"; |
|||
|
|||
public abstract CancellationToken Token { get; } |
|||
|
|||
protected IAmbientScopeProvider<CancellationTokenOverride> CancellationTokenOverrideScopeProvider { get; } |
|||
|
|||
protected CancellationTokenOverride OverrideValue => CancellationTokenOverrideScopeProvider.GetValue(CancellationTokenOverrideContextKey); |
|||
|
|||
protected CancellationTokenProviderBase(IAmbientScopeProvider<CancellationTokenOverride> cancellationTokenOverrideScopeProvider) |
|||
{ |
|||
CancellationTokenOverrideScopeProvider = cancellationTokenOverrideScopeProvider; |
|||
} |
|||
|
|||
public IDisposable Use(CancellationToken cancellationToken) |
|||
{ |
|||
return CancellationTokenOverrideScopeProvider.BeginScope(CancellationTokenOverrideContextKey, new CancellationTokenOverride(cancellationToken)); |
|||
} |
|||
} |
|||
} |
|||
@ -1,9 +1,12 @@ |
|||
using System.Threading; |
|||
using System; |
|||
using System.Threading; |
|||
|
|||
namespace Volo.Abp.Threading |
|||
{ |
|||
public interface ICancellationTokenProvider |
|||
{ |
|||
CancellationToken Token { get; } |
|||
|
|||
IDisposable Use(CancellationToken cancellationToken); |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,16 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.test.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" /> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.Threading\Volo.Abp.Threading.csproj" /> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,15 @@ |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.Threading |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpThreadingModule), |
|||
typeof(AbpTestBaseModule) |
|||
)] |
|||
public class AbpThreadingTestModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
using System; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Shouldly; |
|||
using Volo.Abp.Testing; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.Threading |
|||
{ |
|||
public class NullCancellationTokenProvider_Tests : AbpIntegratedTest<AbpThreadingTestModule> |
|||
{ |
|||
private readonly ICancellationTokenProvider _cancellationTokenProvider; |
|||
|
|||
public NullCancellationTokenProvider_Tests() |
|||
{ |
|||
_cancellationTokenProvider = NullCancellationTokenProvider.Instance; |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Return_None_Token() |
|||
{ |
|||
_cancellationTokenProvider.Token.ShouldBe(CancellationToken.None); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Return_Specific_Token() |
|||
{ |
|||
var cts = new CancellationTokenSource(); |
|||
|
|||
using (_cancellationTokenProvider.Use(cts.Token)) |
|||
{ |
|||
var newCancellationTokenProvider = NullCancellationTokenProvider.Instance; |
|||
|
|||
newCancellationTokenProvider.Token.ShouldBe(cts.Token); |
|||
} |
|||
|
|||
_cancellationTokenProvider.Token.ShouldBe(CancellationToken.None); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Cancel_After_100_Milliseconds() |
|||
{ |
|||
var cts = new CancellationTokenSource(); |
|||
cts.CancelAfter(TimeSpan.FromMilliseconds(100)); |
|||
|
|||
using (_cancellationTokenProvider.Use(cts.Token)) |
|||
{ |
|||
var newCancellationTokenProvider = NullCancellationTokenProvider.Instance; |
|||
Should.Throw<OperationCanceledException>(() => LongTask(1000, newCancellationTokenProvider.Token)); |
|||
} |
|||
} |
|||
|
|||
private void LongTask(int loopCounter, CancellationToken cancellationToken = default) |
|||
{ |
|||
for (var i = 0; i < loopCounter; i++) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
|
|||
Thread.Sleep(10); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue