Skip to content

Commit da9bebe

Browse files
authored
Add code example for CA2012 rule (#49037) (#49038)
1 parent 1da7b6d commit da9bebe

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

docs/fundamentals/code-analysis/quality-rules/ca2012.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ helpviewer_keywords:
1010
- "CA2012"
1111
author: stephentoub
1212
ms.author: stoub
13+
dev_langs:
14+
- CSharp
1315
---
1416
# CA2012: Use ValueTasks correctly
1517

@@ -37,6 +39,10 @@ In general, ValueTasks should be directly awaited rather than discarded or store
3739

3840
For `ValueTask` objects returned from arbitrary member calls, the caller needs to assume that the `ValueTask` must be consumed (for example, awaited) once and only once. However, if the developer also controls the member being invoked and has complete knowledge of its implementation, the developer may know it's safe to suppress the warning, for example, if the return `ValueTask` always wraps a <xref:System.Threading.Tasks.Task> object.
3941

42+
## Example
43+
44+
:::code language="csharp" source="snippets/csharp/all-rules/ca2012.cs" id="snippet1":::
45+
4046
## Suppress a warning
4147

4248
If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System.Threading.Tasks;
2+
3+
namespace ca2012
4+
{
5+
//<snippet1>
6+
public class NumberValueTask
7+
{
8+
public async ValueTask<int> GetNumberAsync()
9+
{
10+
await Task.Delay(100);
11+
return 123;
12+
}
13+
14+
public async Task UseValueTaskIncorrectlyAsync()
15+
{
16+
// This code violates the rule,
17+
// because ValueTask is awaited multiple times
18+
ValueTask<int> numberValueTask = GetNumberAsync();
19+
20+
int first = await numberValueTask;
21+
int second = await numberValueTask; // <- illegal reuse
22+
23+
// ...
24+
}
25+
26+
// This code satisfies the rule.
27+
public async Task UseValueTaskCorrectlyAsync()
28+
{
29+
int first = await GetNumberAsync();
30+
int second = await GetNumberAsync();
31+
32+
// ..
33+
}
34+
35+
public async Task UseValueTaskAsTaskAsync()
36+
{
37+
ValueTask<int> numberValueTask = GetNumberAsync();
38+
39+
Task<int> numberTask = numberValueTask.AsTask();
40+
41+
int first = await numberTask;
42+
int second = await numberTask;
43+
44+
// ...
45+
}
46+
}
47+
//</snippet1>
48+
}

0 commit comments

Comments
 (0)