Skip to content

Commit 3ed53cf

Browse files
Merge pull request #134 from daviddotcs/cancellation-token-overloads
Add CancellationToken overloads to Compile methods
2 parents 3a41c59 + b6c9f6e commit 3ed53cf

File tree

3 files changed

+83
-18
lines changed

3 files changed

+83
-18
lines changed

RazorEngineCore.Tests/TestCompileAndRun.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
namespace RazorEngineCore.Tests
1414
{
1515
using System.Runtime.InteropServices;
16+
using System.Threading;
1617

1718
[TestClass]
1819
public class TestCompileAndRun
@@ -728,6 +729,66 @@ @using TestAssembly
728729
Assert.AreEqual(expected, actual);
729730
}
730731

732+
[TestMethod]
733+
public void TestCompileCancellation_DynamicModel()
734+
{
735+
RazorEngine razorEngine = new RazorEngine();
736+
using (CancellationTokenSource cancellationSource = new CancellationTokenSource())
737+
{
738+
cancellationSource.Cancel();
739+
740+
Assert.ThrowsException<OperationCanceledException>(() =>
741+
{
742+
IRazorEngineCompiledTemplate template = razorEngine.Compile("Hello @Model.Name", cancellationToken: cancellationSource.Token);
743+
});
744+
}
745+
}
746+
747+
[TestMethod]
748+
public async Task TestCompileCancellation_DynamicModelAsync()
749+
{
750+
RazorEngine razorEngine = new RazorEngine();
751+
using (CancellationTokenSource cancellationSource = new CancellationTokenSource())
752+
{
753+
cancellationSource.Cancel();
754+
755+
await Assert.ThrowsExceptionAsync<OperationCanceledException>(async () =>
756+
{
757+
IRazorEngineCompiledTemplate template = await razorEngine.CompileAsync("Hello @Model.Name", cancellationToken: cancellationSource.Token);
758+
});
759+
}
760+
}
761+
762+
[TestMethod]
763+
public void TestCompileCancellation_TypedModel1()
764+
{
765+
RazorEngine razorEngine = new RazorEngine();
766+
using (CancellationTokenSource cancellationSource = new CancellationTokenSource())
767+
{
768+
cancellationSource.Cancel();
769+
770+
Assert.ThrowsException<OperationCanceledException>(() =>
771+
{
772+
IRazorEngineCompiledTemplate<TestTemplate1> template = razorEngine.Compile<TestTemplate1>("Hello @A @B @(A + B) @C @Decorator(\"777\")", cancellationToken: cancellationSource.Token);
773+
});
774+
}
775+
}
776+
777+
[TestMethod]
778+
public async Task TestCompileCancellation_TypedModel1Async()
779+
{
780+
RazorEngine razorEngine = new RazorEngine();
781+
using (CancellationTokenSource cancellationSource = new CancellationTokenSource())
782+
{
783+
cancellationSource.Cancel();
784+
785+
await Assert.ThrowsExceptionAsync<OperationCanceledException>(async () =>
786+
{
787+
IRazorEngineCompiledTemplate<TestTemplate1> template = await razorEngine.CompileAsync<TestTemplate1>("Hello @A @B @(A + B) @C @Decorator(\"777\")", cancellationToken: cancellationSource.Token);
788+
});
789+
}
790+
}
791+
731792
private static List<MetadataReference> GetMetadataReferences()
732793
{
733794
if (RuntimeInformation.FrameworkDescription.StartsWith(

RazorEngineCore/IRazorEngine.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
using System;
2+
using System.Threading;
23
using System.Threading.Tasks;
34

45
namespace RazorEngineCore
56
{
67
public interface IRazorEngine
78
{
8-
IRazorEngineCompiledTemplate<T> Compile<T>(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null)
9+
IRazorEngineCompiledTemplate<T> Compile<T>(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null, CancellationToken cancellationToken = default)
910
where T : IRazorEngineTemplate;
10-
11-
Task<IRazorEngineCompiledTemplate<T>> CompileAsync<T>(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null)
11+
12+
Task<IRazorEngineCompiledTemplate<T>> CompileAsync<T>(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null, CancellationToken cancellationToken = default)
1213
where T : IRazorEngineTemplate;
1314

14-
IRazorEngineCompiledTemplate Compile(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null);
15+
IRazorEngineCompiledTemplate Compile(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null, CancellationToken cancellationToken = default);
1516

16-
Task<IRazorEngineCompiledTemplate> CompileAsync(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null);
17+
Task<IRazorEngineCompiledTemplate> CompileAsync(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null, CancellationToken cancellationToken = default);
1718
}
1819
}

RazorEngineCore/RazorEngine.cs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.IO;
44
using System.Linq;
55
using System.Text;
6+
using System.Threading;
67
using System.Threading.Tasks;
78
using Microsoft.AspNetCore.Razor.Language;
89
using Microsoft.CodeAnalysis;
@@ -15,41 +16,42 @@ namespace RazorEngineCore
1516
{
1617
public class RazorEngine : IRazorEngine
1718
{
18-
public IRazorEngineCompiledTemplate<T> Compile<T>(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null) where T : IRazorEngineTemplate
19+
public IRazorEngineCompiledTemplate<T> Compile<T>(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null, CancellationToken cancellationToken = default) where T : IRazorEngineTemplate
1920
{
2021
IRazorEngineCompilationOptionsBuilder compilationOptionsBuilder = new RazorEngineCompilationOptionsBuilder();
2122
compilationOptionsBuilder.AddAssemblyReference(typeof(T).Assembly);
2223
compilationOptionsBuilder.Inherits(typeof(T));
2324

2425
builderAction?.Invoke(compilationOptionsBuilder);
2526

26-
RazorEngineCompiledTemplateMeta meta = this.CreateAndCompileToStream(content, compilationOptionsBuilder.Options);
27+
MemoryStream memoryStream = this.CreateAndCompileToStream(content, compilationOptionsBuilder.Options, cancellationToken);
2728

2829
return new RazorEngineCompiledTemplate<T>(meta);
2930
}
3031

31-
public Task<IRazorEngineCompiledTemplate<T>> CompileAsync<T>(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null) where T : IRazorEngineTemplate
32+
public Task<IRazorEngineCompiledTemplate<T>> CompileAsync<T>(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null, CancellationToken cancellationToken = default) where T : IRazorEngineTemplate
3233
{
33-
return Task.Factory.StartNew(() => this.Compile<T>(content: content, builderAction: builderAction));
34+
return Task.Factory.StartNew(() => this.Compile<T>(content: content, builderAction: builderAction, cancellationToken: cancellationToken));
3435
}
3536

36-
public IRazorEngineCompiledTemplate Compile(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null)
37+
public IRazorEngineCompiledTemplate Compile(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null, CancellationToken cancellationToken = default)
3738
{
3839
IRazorEngineCompilationOptionsBuilder compilationOptionsBuilder = new RazorEngineCompilationOptionsBuilder();
3940
compilationOptionsBuilder.Inherits(typeof(RazorEngineTemplateBase));
4041

4142
builderAction?.Invoke(compilationOptionsBuilder);
42-
43-
RazorEngineCompiledTemplateMeta meta = this.CreateAndCompileToStream(content, compilationOptionsBuilder.Options);
43+
44+
RazorEngineCompiledTemplateMeta meta = this.CreateAndCompileToStream(content, compilationOptionsBuilder.Options, cancellationToken);
4445
return new RazorEngineCompiledTemplate(meta);
4546
}
4647

47-
public Task<IRazorEngineCompiledTemplate> CompileAsync(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null)
48+
public Task<IRazorEngineCompiledTemplate> CompileAsync(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null, CancellationToken cancellationToken = default)
4849
{
49-
return Task.Factory.StartNew(() => this.Compile(content: content, builderAction: builderAction));
50+
return Task.Factory.StartNew(() => this.Compile(content: content, builderAction: builderAction, cancellationToken: cancellationToken));
5051
}
5152

52-
protected virtual RazorEngineCompiledTemplateMeta CreateAndCompileToStream(string templateSource, RazorEngineCompilationOptions options)
53+
protected virtual RazorEngineCompiledTemplateMeta CreateAndCompileToStream(string templateSource, RazorEngineCompilationOptions options, CancellationToken cancellationToken)
54+
5355
{
5456
templateSource = this.WriteDirectives(templateSource, options);
5557
string projectPath = @".";
@@ -75,9 +77,9 @@ protected virtual RazorEngineCompiledTemplateMeta CreateAndCompileToStream(strin
7577
new List<TagHelperDescriptor>());
7678

7779

78-
7980
RazorCSharpDocument razorCSharpDocument = codeDocument.GetCSharpDocument();
80-
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(razorCSharpDocument.GeneratedCode);
81+
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(razorCSharpDocument.GeneratedCode, cancellationToken: cancellationToken);
82+
8183

8284
CSharpCompilation compilation = CSharpCompilation.Create(
8385
fileName,
@@ -110,7 +112,8 @@ protected virtual RazorEngineCompiledTemplateMeta CreateAndCompileToStream(strin
110112
MemoryStream assemblyStream = new MemoryStream();
111113
MemoryStream pdbStream = options.IncludeDebuggingInfo ? new MemoryStream() : null;
112114

113-
EmitResult emitResult = compilation.Emit(assemblyStream, pdbStream);
115+
EmitResult emitResult = compilation.Emit(assemblyStream, pdbStream, cancellationToken: cancellationToken);
116+
114117

115118
if (!emitResult.Success)
116119
{

0 commit comments

Comments
 (0)