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 |
namespace Volo.Abp.Threading |
||||
{ |
{ |
||||
public interface ICancellationTokenProvider |
public interface ICancellationTokenProvider |
||||
{ |
{ |
||||
CancellationToken Token { get; } |
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