Skip to content

Commit d35f5c7

Browse files
Fill the incomplete usage of async methods.
- Prefer Task.Run over Task.Factory.StartNew - Compile in release mode with overflow checks for safety. - Implement `await using` when available. - Remove unused `result.GetType();` - CA1835: Prefer the memory-based overloads of ReadAsync/WriteAsync
1 parent 73ce9cf commit d35f5c7

10 files changed

+75
-61
lines changed

RazorEngineCore.Tests/TestCompileAndRun.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ public void TestCompileCancellation_DynamicModel()
739739

740740
Assert.ThrowsException<OperationCanceledException>(() =>
741741
{
742-
IRazorEngineCompiledTemplate template = razorEngine.Compile("Hello @Model.Name", cancellationToken: cancellationSource.Token);
742+
_ = razorEngine.Compile("Hello @Model.Name", cancellationToken: cancellationSource.Token);
743743
});
744744
}
745745
}
@@ -754,7 +754,7 @@ public async Task TestCompileCancellation_DynamicModelAsync()
754754

755755
await Assert.ThrowsExceptionAsync<OperationCanceledException>(async () =>
756756
{
757-
IRazorEngineCompiledTemplate template = await razorEngine.CompileAsync("Hello @Model.Name", cancellationToken: cancellationSource.Token);
757+
_ = await razorEngine.CompileAsync("Hello @Model.Name", cancellationToken: cancellationSource.Token);
758758
});
759759
}
760760
}
@@ -769,7 +769,7 @@ public void TestCompileCancellation_TypedModel1()
769769

770770
Assert.ThrowsException<OperationCanceledException>(() =>
771771
{
772-
IRazorEngineCompiledTemplate<TestTemplate1> template = razorEngine.Compile<TestTemplate1>("Hello @A @B @(A + B) @C @Decorator(\"777\")", cancellationToken: cancellationSource.Token);
772+
_ = razorEngine.Compile<TestTemplate1>("Hello @A @B @(A + B) @C @Decorator(\"777\")", cancellationToken: cancellationSource.Token);
773773
});
774774
}
775775
}
@@ -784,7 +784,7 @@ public async Task TestCompileCancellation_TypedModel1Async()
784784

785785
await Assert.ThrowsExceptionAsync<OperationCanceledException>(async () =>
786786
{
787-
IRazorEngineCompiledTemplate<TestTemplate1> template = await razorEngine.CompileAsync<TestTemplate1>("Hello @A @B @(A + B) @C @Decorator(\"777\")", cancellationToken: cancellationSource.Token);
787+
_ = await razorEngine.CompileAsync<TestTemplate1>("Hello @A @B @(A + B) @C @Decorator(\"777\")", cancellationToken: cancellationSource.Token);
788788
});
789789
}
790790
}

RazorEngineCore/AnonymousTypeWrapper.cs

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public override bool TryGetMember(GetMemberBinder binder, out object result)
3232
return true;
3333
}
3434

35-
var type = result.GetType();
35+
//var type = result.GetType();
3636

3737
if (result.IsAnonymous())
3838
{
@@ -41,12 +41,7 @@ public override bool TryGetMember(GetMemberBinder binder, out object result)
4141

4242
if (result is IDictionary dictionary)
4343
{
44-
List<object> keys = new List<object>();
45-
46-
foreach(object key in dictionary.Keys)
47-
{
48-
keys.Add(key);
49-
}
44+
List<object> keys = dictionary.Keys.Cast<object>().ToList();
5045

5146
foreach(object key in keys)
5247
{
@@ -56,22 +51,13 @@ public override bool TryGetMember(GetMemberBinder binder, out object result)
5651
}
5752
}
5853
}
59-
else if (result is IEnumerable enumerable && !(result is string))
54+
else if (result is IEnumerable enumerable and not string)
6055
{
6156
result = enumerable.Cast<object>()
62-
.Select(e =>
63-
{
64-
if (e.IsAnonymous())
65-
{
66-
return new AnonymousTypeWrapper(e);
67-
}
68-
69-
return e;
70-
})
57+
.Select(e => e.IsAnonymous() ? new AnonymousTypeWrapper(e) : e)
7158
.ToList();
7259
}
73-
74-
60+
7561
return true;
7662
}
7763
}

RazorEngineCore/ObjectExtenders.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.IO;
55
using System.Reflection;
66
using System.Runtime.CompilerServices;
7+
using System.Threading.Tasks;
78

89
namespace RazorEngineCore
910
{
@@ -32,18 +33,25 @@ public static bool IsAnonymous(this object obj)
3233
&& type.Attributes.HasFlag(TypeAttributes.NotPublic);
3334
}
3435

35-
public static long ReadLong(this Stream stream)
36+
public static async Task<long> ReadLong(this Stream stream)
3637
{
3738
byte[] buffer = new byte[8];
38-
stream.Read(buffer, 0, 8);
39-
39+
#if NETSTANDARD2_0
40+
_ = await stream.ReadAsync(buffer, 0, buffer.Length);
41+
#else
42+
_ = await stream.ReadAsync(buffer.AsMemory(0, buffer.Length));
43+
#endif
4044
return BitConverter.ToInt64(buffer, 0);
4145
}
4246

43-
public static void WriteLong(this Stream stream, long value)
47+
public static async Task WriteLong(this Stream stream, long value)
4448
{
4549
byte[] buffer = BitConverter.GetBytes(value);
46-
stream.Write(buffer, 0, buffer.Length);
50+
#if NETSTANDARD2_0
51+
await stream.WriteAsync(buffer, 0, buffer.Length);
52+
#else
53+
await stream.WriteAsync(buffer);
54+
#endif
4755
}
4856
}
4957
}

RazorEngineCore/RazorEngine.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public IRazorEngineCompiledTemplate<T> Compile<T>(string content, Action<IRazorE
3030

3131
public Task<IRazorEngineCompiledTemplate<T>> CompileAsync<T>(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null, CancellationToken cancellationToken = default) where T : IRazorEngineTemplate
3232
{
33-
return Task.Factory.StartNew(() => this.Compile<T>(content: content, builderAction: builderAction, cancellationToken: cancellationToken));
33+
return Task.Run(() => this.Compile<T>(content: content, builderAction: builderAction, cancellationToken: cancellationToken));
3434
}
3535

3636
public IRazorEngineCompiledTemplate Compile(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null, CancellationToken cancellationToken = default)
@@ -46,7 +46,7 @@ public IRazorEngineCompiledTemplate Compile(string content, Action<IRazorEngineC
4646

4747
public Task<IRazorEngineCompiledTemplate> CompileAsync(string content, Action<IRazorEngineCompilationOptionsBuilder> builderAction = null, CancellationToken cancellationToken = default)
4848
{
49-
return Task.Factory.StartNew(() => this.Compile(
49+
return Task.Run(() => this.Compile(
5050
content,
5151
builderAction,
5252
cancellationToken));
@@ -105,7 +105,9 @@ protected virtual RazorEngineCompiledTemplateMeta CreateAndCompileToStream(strin
105105
})
106106
.Concat(options.MetadataReferences)
107107
.ToList(),
108-
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
108+
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
109+
.WithOptimizationLevel(OptimizationLevel.Release)
110+
.WithOverflowChecks(true));
109111

110112

111113
MemoryStream assemblyStream = new MemoryStream();

RazorEngineCore/RazorEngineCompilationOptionsBuilder.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,10 @@ private string RenderTypeName(Type type)
6363

6464
string result = string.Join(".", elements.Where(e => !string.IsNullOrWhiteSpace(e)));
6565

66-
if (result.Contains('`'))
66+
int tildeLocation = result.IndexOf('`');
67+
if (tildeLocation > -1)
6768
{
68-
result = result.Substring(0, result.IndexOf("`"));
69+
result = result.Substring(0, tildeLocation);
6970
}
7071

7172
if (type.GenericTypeArguments.Length == 0)

RazorEngineCore/RazorEngineCompiledTemplate.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,17 @@ public static RazorEngineCompiledTemplate LoadFromFile(string fileName)
2222

2323
public static async Task<RazorEngineCompiledTemplate> LoadFromFileAsync(string fileName)
2424
{
25+
#if NETSTANDARD2_0
2526
using (FileStream fileStream = new FileStream(
26-
path: fileName,
27-
mode: FileMode.Open,
28-
access: FileAccess.Read,
29-
share: FileShare.None,
30-
bufferSize: 4096,
31-
useAsync: true))
27+
#else
28+
await using (FileStream fileStream = new FileStream(
29+
#endif
30+
path: fileName,
31+
mode: FileMode.Open,
32+
access: FileAccess.Read,
33+
share: FileShare.None,
34+
bufferSize: 4096,
35+
useAsync: true))
3236
{
3337
return await LoadFromStreamAsync(fileStream);
3438
}

RazorEngineCore/RazorEngineCompiledTemplateBase.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.IO;
22
using System;
3-
using System.Text;
43
using System.Threading.Tasks;
54

65
namespace RazorEngineCore
@@ -19,7 +18,11 @@ public void SaveToFile(string fileName)
1918

2019
public async Task SaveToFileAsync(string fileName)
2120
{
21+
#if NETSTANDARD2_0
2222
using (FileStream fileStream = new FileStream(
23+
#else
24+
await using (FileStream fileStream = new FileStream(
25+
#endif
2326
path: fileName,
2427
mode: FileMode.OpenOrCreate,
2528
access: FileAccess.Write,
@@ -36,9 +39,9 @@ public void SaveToStream(Stream stream)
3639
this.SaveToStreamAsync(stream).GetAwaiter().GetResult();
3740
}
3841

39-
public async Task SaveToStreamAsync(Stream stream)
42+
public Task SaveToStreamAsync(Stream stream)
4043
{
41-
await this.Meta.Write(stream);
44+
return this.Meta.Write(stream);
4245
}
4346

4447
public void EnableDebugging(string debuggingOutputDirectory = null)

RazorEngineCore/RazorEngineCompiledTemplateMeta.cs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
using System.IO;
1+
using System.IO;
32
using System.Text;
43
using System.Threading.Tasks;
54

@@ -16,7 +15,7 @@ public class RazorEngineCompiledTemplateMeta
1615

1716
public async Task Write(Stream stream)
1817
{
19-
stream.WriteLong(10001);
18+
await stream.WriteLong(10001);
2019

2120
await this.WriteBuffer(stream, this.AssemblyByteCode);
2221
await this.WriteBuffer(stream, this.PdbByteCode);
@@ -28,7 +27,7 @@ public async Task Write(Stream stream)
2827

2928
public static async Task<RazorEngineCompiledTemplateMeta> Read(Stream stream)
3029
{
31-
long version = stream.ReadLong();
30+
long version = await stream.ReadLong();
3231

3332
if (version == 10001)
3433
{
@@ -51,22 +50,26 @@ private static async Task<RazorEngineCompiledTemplateMeta> LoadVersion1(Stream s
5150
};
5251
}
5352

54-
private async Task WriteString(Stream stream, string value)
53+
private Task WriteString(Stream stream, string value)
5554
{
5655
byte[] buffer = value == null ? null : Encoding.UTF8.GetBytes(value);
57-
await this.WriteBuffer(stream, buffer);
56+
return this.WriteBuffer(stream, buffer);
5857
}
5958

6059
private async Task WriteBuffer(Stream stream, byte[] buffer)
6160
{
6261
if (buffer == null)
6362
{
64-
stream.WriteLong(0);
63+
await stream.WriteLong(0);
6564
return;
6665
}
6766

68-
stream.WriteLong(buffer.Length);
67+
await stream.WriteLong(buffer.Length);
68+
#if NETSTANDARD2_0
6969
await stream.WriteAsync(buffer, 0, buffer.Length);
70+
#else
71+
await stream.WriteAsync(buffer);
72+
#endif
7073
}
7174

7275
private static async Task<string> ReadString(Stream stream)
@@ -77,16 +80,19 @@ private static async Task<string> ReadString(Stream stream)
7780

7881
private static async Task<byte[]> ReadBuffer(Stream stream)
7982
{
80-
long length = stream.ReadLong();
83+
long length = await stream.ReadLong();
8184

8285
if (length == 0)
8386
{
8487
return null;
8588
}
8689

8790
byte[] buffer = new byte[length];
88-
await stream.ReadAsync(buffer, 0, buffer.Length);
89-
91+
#if NETSTANDARD2_0
92+
_ = await stream.ReadAsync(buffer, 0, buffer.Length);
93+
#else
94+
_ = await stream.ReadAsync(buffer);
95+
#endif
9096
return buffer;
9197
}
9298
}

RazorEngineCore/RazorEngineCompiledTemplateT.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.IO;
33
using System.Reflection;
44
using System.Threading.Tasks;
5-
using Microsoft.CodeAnalysis.CSharp.Syntax;
65

76
namespace RazorEngineCore
87
{
@@ -24,13 +23,17 @@ public static RazorEngineCompiledTemplate<T> LoadFromFile(string fileName)
2423

2524
public static async Task<RazorEngineCompiledTemplate<T>> LoadFromFileAsync(string fileName)
2625
{
26+
#if NETSTANDARD2_0
2727
using (FileStream fileStream = new FileStream(
28-
path: fileName,
29-
mode: FileMode.Open,
30-
access: FileAccess.Read,
31-
share: FileShare.None,
32-
bufferSize: 4096,
33-
useAsync: true))
28+
#else
29+
await using (FileStream fileStream = new FileStream(
30+
#endif
31+
path: fileName,
32+
mode: FileMode.Open,
33+
access: FileAccess.Read,
34+
share: FileShare.None,
35+
bufferSize: 4096,
36+
useAsync: true))
3437
{
3538
return await LoadFromStreamAsync(fileStream);
3639
}
@@ -53,7 +56,7 @@ public string Run(Action<T> initializer)
5356

5457
public async Task<string> RunAsync(Action<T> initializer)
5558
{
56-
T instance = (T) Activator.CreateInstance(this.TemplateType);
59+
var instance = (T) Activator.CreateInstance(this.TemplateType);
5760
initializer(instance);
5861

5962
if (this.IsDebuggerEnabled && instance is RazorEngineTemplateBase instance2)

RazorEngineCore/RazorEngineCore.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<Company>Alexander Selishchev</Company>
1313
<SignAssembly>true</SignAssembly>
1414
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
15+
<LangVersion>latest</LangVersion>
1516
</PropertyGroup>
1617
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
1718
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

0 commit comments

Comments
 (0)