diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers.md
index 439fc000c36f..6ab1a4a31015 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers.md
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers.md
@@ -1908,6 +1908,18 @@ In many situations, logging is disabled or set to a log level that results in an
|CodeFix|True|
---
+## [CA1876](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1876): Do not use 'AsParallel' in 'foreach'
+
+Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+|Item|Value|
+|-|-|
+|Category|Performance|
+|Enabled|True|
+|Severity|Info|
+|CodeFix|False|
+---
+
## [CA2000](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2000): Dispose objects before losing scope
If a disposable object is not explicitly disposed before all references to it are out of scope, the object will be disposed at some indeterminate time when the garbage collector runs the finalizer of the object. Because an exceptional event might occur that will prevent the finalizer of the object from running, the object should be explicitly disposed instead.
@@ -2166,6 +2178,18 @@ JsonDocument implements IDisposable and needs to be properly disposed. When only
|CodeFix|True|
---
+## [CA2027](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2027): Cancel Task.Delay after Task.WhenAny completes
+
+When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+|Item|Value|
+|-|-|
+|Category|Reliability|
+|Enabled|True|
+|Severity|Info|
+|CodeFix|False|
+---
+
## [CA2100](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2100): Review SQL queries for security vulnerabilities
SQL queries that directly use user input can be vulnerable to SQL injection attacks. Review this SQL query for potential vulnerabilities, and consider using a parameterized SQL query.
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers.sarif
index b9092f16d745..5cc63d324b73 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers.sarif
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers.sarif
@@ -3507,6 +3507,26 @@
]
}
},
+ "CA1876": {
+ "id": "CA1876",
+ "shortDescription": "Do not use 'AsParallel' in 'foreach'",
+ "fullDescription": "Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.",
+ "defaultLevel": "note",
+ "helpUri": "https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1876",
+ "properties": {
+ "category": "Performance",
+ "isEnabledByDefault": true,
+ "typeName": "DoNotUseAsParallelInForEachLoopAnalyzer",
+ "languages": [
+ "C#",
+ "Visual Basic"
+ ],
+ "tags": [
+ "Telemetry",
+ "EnabledRuleInAggressiveMode"
+ ]
+ }
+ },
"CA2000": {
"id": "CA2000",
"shortDescription": "Dispose objects before losing scope",
@@ -3870,6 +3890,26 @@
]
}
},
+ "CA2027": {
+ "id": "CA2027",
+ "shortDescription": "Cancel Task.Delay after Task.WhenAny completes",
+ "fullDescription": "When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.",
+ "defaultLevel": "note",
+ "helpUri": "https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2027",
+ "properties": {
+ "category": "Reliability",
+ "isEnabledByDefault": true,
+ "typeName": "DoNotUseNonCancelableTaskDelayWithWhenAny",
+ "languages": [
+ "C#",
+ "Visual Basic"
+ ],
+ "tags": [
+ "Telemetry",
+ "EnabledRuleInAggressiveMode"
+ ]
+ }
+ },
"CA2100": {
"id": "CA2100",
"shortDescription": "Review SQL queries for security vulnerabilities",
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/AnalyzerReleases.Unshipped.md b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/AnalyzerReleases.Unshipped.md
index 589e86fc4126..1f7f1b3a72a1 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/AnalyzerReleases.Unshipped.md
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/AnalyzerReleases.Unshipped.md
@@ -7,7 +7,9 @@ Rule ID | Category | Severity | Notes
CA1873 | Performance | Info | AvoidPotentiallyExpensiveCallWhenLoggingAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873)
CA1874 | Performance | Info | UseRegexMembers, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1874)
CA1875 | Performance | Info | UseRegexMembers, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1875)
+CA1876 | Performance | Info | DoNotUseAsParallelInForEachLoopAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1876)
CA2023 | Reliability | Warning | LoggerMessageDefineAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2023)
CA2024 | Reliability | Warning | DoNotUseEndOfStreamInAsyncMethods, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2024)
CA2025 | Reliability | Disabled | DoNotPassDisposablesIntoUnawaitedTasksAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2025)
CA2026 | Reliability | Info | PreferJsonElementParse, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2026)
+CA2027 | Reliability | Info | DoNotUseNonCancelableTaskDelayWithWhenAny, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2027)
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
index ecb112fa90b4..0c0999c373b9 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
@@ -195,6 +195,15 @@
Do not use Count() or LongCount() when Any() can be used
+
+ Do not use 'AsParallel' in 'foreach'
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
Prefer 'Convert.ToHexString' and 'Convert.ToHexStringLower' over call chains based on 'BitConverter.ToString'
@@ -1637,6 +1646,15 @@
Replace 'WhenAll' call with argument
+
+ Cancel Task.Delay after Task.WhenAny completes
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
Use 'string.Equals'
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/Performance/DoNotUseAsParallelInForEachLoop.cs b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/Performance/DoNotUseAsParallelInForEachLoop.cs
new file mode 100644
index 000000000000..c7e41f770684
--- /dev/null
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/Performance/DoNotUseAsParallelInForEachLoop.cs
@@ -0,0 +1,100 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using System.Collections.Immutable;
+using System.Linq;
+using Analyzer.Utilities;
+using Analyzer.Utilities.Extensions;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Operations;
+
+namespace Microsoft.NetCore.Analyzers.Performance
+{
+ using static MicrosoftNetCoreAnalyzersResources;
+
+ ///
+ /// CA1876:
+ /// Analyzer to detect misuse of AsParallel() when used directly in a foreach loop.
+ ///
+ [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
+ public sealed class DoNotUseAsParallelInForEachLoopAnalyzer : DiagnosticAnalyzer
+ {
+ internal const string RuleId = "CA1876";
+
+ internal static readonly DiagnosticDescriptor Rule = DiagnosticDescriptorHelper.Create(
+ RuleId,
+ CreateLocalizableResourceString(nameof(DoNotUseAsParallelInForEachLoopTitle)),
+ CreateLocalizableResourceString(nameof(DoNotUseAsParallelInForEachLoopMessage)),
+ DiagnosticCategory.Performance,
+ RuleLevel.IdeSuggestion,
+ description: CreateLocalizableResourceString(nameof(DoNotUseAsParallelInForEachLoopDescription)),
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);
+
+ public override void Initialize(AnalysisContext context)
+ {
+ context.EnableConcurrentExecution();
+ context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
+ context.RegisterCompilationStartAction(OnCompilationStart);
+ }
+
+ private static void OnCompilationStart(CompilationStartAnalysisContext context)
+ {
+ var typeProvider = WellKnownTypeProvider.GetOrCreate(context.Compilation);
+
+ // Get the ParallelEnumerable type
+ var parallelEnumerableType = typeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemLinqParallelEnumerable);
+
+ if (parallelEnumerableType == null)
+ {
+ return;
+ }
+
+ // Get all AsParallel methods - use SymbolEqualityComparer for proper comparison
+ var asParallelMethods = ImmutableHashSet.CreateRange(
+ SymbolEqualityComparer.Default,
+ parallelEnumerableType.GetMembers("AsParallel").OfType());
+
+ if (asParallelMethods.IsEmpty)
+ {
+ return;
+ }
+
+ context.RegisterOperationAction(ctx => AnalyzeForEachLoop(ctx, asParallelMethods), OperationKind.Loop);
+ }
+
+ private static void AnalyzeForEachLoop(OperationAnalysisContext context, ImmutableHashSet asParallelMethods)
+ {
+ if (context.Operation is not IForEachLoopOperation forEachLoop)
+ {
+ return;
+ }
+
+ // Check if the collection is a direct result of AsParallel()
+ var collection = forEachLoop.Collection;
+
+ // Walk up conversions to find the actual operation
+ while (collection is IConversionOperation conversion)
+ {
+ collection = conversion.Operand;
+ }
+
+ // Check if this is an invocation of AsParallel
+ if (collection is IInvocationOperation invocation)
+ {
+ var targetMethod = invocation.TargetMethod;
+
+ // For extension methods, we need to check the ReducedFrom or the original method
+ var methodToCheck = targetMethod.ReducedFrom ?? targetMethod;
+
+ if (asParallelMethods.Contains(methodToCheck.OriginalDefinition))
+ {
+ // Report diagnostic on the AsParallel call
+ context.ReportDiagnostic(invocation.CreateDiagnostic(Rule));
+ }
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/Tasks/DoNotUseNonCancelableTaskDelayWithWhenAny.cs b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/Tasks/DoNotUseNonCancelableTaskDelayWithWhenAny.cs
new file mode 100644
index 000000000000..d8c17a1adca0
--- /dev/null
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/Tasks/DoNotUseNonCancelableTaskDelayWithWhenAny.cs
@@ -0,0 +1,152 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using System.Collections.Immutable;
+using Analyzer.Utilities;
+using Analyzer.Utilities.Extensions;
+using Analyzer.Utilities.Lightup;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Operations;
+using static Microsoft.NetCore.Analyzers.MicrosoftNetCoreAnalyzersResources;
+
+namespace Microsoft.NetCore.Analyzers.Tasks
+{
+ ///
+ /// CA2027:
+ ///
+ [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
+ public sealed class DoNotUseNonCancelableTaskDelayWithWhenAny : DiagnosticAnalyzer
+ {
+ internal const string RuleId = "CA2027";
+
+ internal static readonly DiagnosticDescriptor Rule = DiagnosticDescriptorHelper.Create(
+ RuleId,
+ CreateLocalizableResourceString(nameof(DoNotUseNonCancelableTaskDelayWithWhenAnyTitle)),
+ CreateLocalizableResourceString(nameof(DoNotUseNonCancelableTaskDelayWithWhenAnyMessage)),
+ DiagnosticCategory.Reliability,
+ RuleLevel.IdeSuggestion,
+ CreateLocalizableResourceString(nameof(DoNotUseNonCancelableTaskDelayWithWhenAnyDescription)),
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);
+
+ public override void Initialize(AnalysisContext context)
+ {
+ context.EnableConcurrentExecution();
+ context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
+
+ context.RegisterCompilationStartAction(context =>
+ {
+ var compilation = context.Compilation;
+
+ if (!compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingTasksTask, out var taskType) ||
+ !compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingCancellationToken, out var cancellationTokenType))
+ {
+ return;
+ }
+
+ context.RegisterOperationAction(context =>
+ {
+ var invocation = (IInvocationOperation)context.Operation;
+
+ // Check if this is a call to Task.WhenAny
+ var method = invocation.TargetMethod;
+ if (!SymbolEqualityComparer.Default.Equals(method.ContainingType, taskType) ||
+ !method.IsStatic ||
+ method.Name != nameof(Task.WhenAny))
+ {
+ return;
+ }
+
+ // Count the total number of tasks passed to WhenAny
+ int taskCount = 0;
+ List? taskDelayOperations = null;
+
+ // Task.WhenAny has params parameters, so arguments are often implicitly wrapped in an array
+ // We need to check inside the array initializer or collection expression
+ for (int i = 0; i < invocation.Arguments.Length; i++)
+ {
+ var argument = invocation.Arguments[i].Value.WalkDownConversion();
+
+ // Check if this is an array creation
+ if (argument is IArrayCreationOperation { Initializer: not null } arrayCreation)
+ {
+ // Check each element in the array
+ foreach (var element in arrayCreation.Initializer.ElementValues)
+ {
+ taskCount++;
+ if (IsNonCancelableTaskDelay(element, taskType, cancellationTokenType))
+ {
+ (taskDelayOperations ??= []).Add(element);
+ }
+ }
+ }
+ else if (ICollectionExpressionOperationWrapper.IsInstance(argument))
+ {
+ // Check each element in the collection expression
+ var collectionExpression = ICollectionExpressionOperationWrapper.FromOperation(argument);
+ foreach (var element in collectionExpression.Elements)
+ {
+ taskCount++;
+ if (IsNonCancelableTaskDelay(element, taskType, cancellationTokenType))
+ {
+ (taskDelayOperations ??= []).Add(element);
+ }
+ }
+ }
+ else
+ {
+ // Direct argument (not params or array)
+ taskCount++;
+ if (IsNonCancelableTaskDelay(argument, taskType, cancellationTokenType))
+ {
+ (taskDelayOperations ??= []).Add(argument);
+ }
+ }
+ }
+
+ // Only report diagnostics if there are at least 2 tasks total
+ // (avoid flagging Task.WhenAny(Task.Delay(...)) which may be used to avoid exceptions)
+ if (taskCount >= 2 && taskDelayOperations is not null)
+ {
+ foreach (var operation in taskDelayOperations)
+ {
+ context.ReportDiagnostic(operation.CreateDiagnostic(Rule));
+ }
+ }
+ }, OperationKind.Invocation);
+ });
+ }
+
+ private static bool IsNonCancelableTaskDelay(IOperation operation, INamedTypeSymbol taskType, INamedTypeSymbol cancellationTokenType)
+ {
+ operation = operation.WalkDownConversion();
+
+ if (operation is not IInvocationOperation invocation)
+ {
+ return false;
+ }
+
+ // Check if this is Task.Delay
+ var method = invocation.TargetMethod;
+ if (!SymbolEqualityComparer.Default.Equals(method.ContainingType, taskType) ||
+ !method.IsStatic ||
+ method.Name != nameof(Task.Delay))
+ {
+ return false;
+ }
+
+ // Check if any parameter is a CancellationToken, in which case we consider it cancelable
+ foreach (var parameter in method.Parameters)
+ {
+ if (SymbolEqualityComparer.Default.Equals(parameter.Type, cancellationTokenType))
+ {
+ return false;
+ }
+ }
+
+ return true; // Task.Delay without CancellationToken
+ }
+ }
+}
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
index 4c369a1a34ad..3da43124d010 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
@@ -1008,6 +1008,21 @@ Rozšíření a uživatelem definované převody se u obecných typů nepodporuj
Pokud chcete využívat jemně odstupňované řízení přístupu a zásady přístupu na úrovni kontejneru, místo SAS účtu použijte SAS služby.
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+
+ Do not use 'AsParallel' in 'foreach'
+ Do not use 'AsParallel' in 'foreach'
+
+ Do Not Use Broken Cryptographic AlgorithmsNepoužívejte prolomené kryptografické algoritmy
@@ -1148,6 +1163,21 @@ Rozšíření a uživatelem definované převody se u obecných typů nepodporuj
{0} je nezabezpečený generátor náhodných čísel. Pokud se pro zabezpečení vyžaduje náhodnost, používejte kryptograficky zabezpečené generátory náhodných čísel.
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+
+ Cancel Task.Delay after Task.WhenAny completes
+ Cancel Task.Delay after Task.WhenAny completes
+
+ Do not use obsolete key derivation functionNepoužívat zastaralou funkci pro odvození klíče
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
index 90c525590d5a..8f3afc60cc61 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
@@ -1008,6 +1008,21 @@ Erweiterungen und benutzerdefinierte Konvertierungen werden bei generischen Type
Für detailliertere Zugriffssteuerung und Zugriffsrichtlinie auf Containerebene die Dienst-SAS anstelle der Konto-SAS verwenden
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+
+ Do not use 'AsParallel' in 'foreach'
+ Do not use 'AsParallel' in 'foreach'
+
+ Do Not Use Broken Cryptographic AlgorithmsKeine beschädigten kryptografischen Algorithmen verwenden
@@ -1148,6 +1163,21 @@ Erweiterungen und benutzerdefinierte Konvertierungen werden bei generischen Type
"{0}" ist ein unsicherer Zufallszahlen-Generator. Verwenden Sie kryptografisch sichere Zufallszahlen-Generatoren, wenn Zufallszahlen für die Sicherheit erforderlich sind.
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+
+ Cancel Task.Delay after Task.WhenAny completes
+ Cancel Task.Delay after Task.WhenAny completes
+
+ Do not use obsolete key derivation functionKeine veraltete Schlüsselableitungsfunktion verwenden
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
index b49c63330fec..4a3e40213544 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
@@ -1008,6 +1008,21 @@ La ampliación y las conversiones definidas por el usuario no se admiten con tip
Use la SAS de servicio en lugar de la SAS de cuenta para el control de acceso detallado y la directiva de acceso de nivel de contenedor
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+
+ Do not use 'AsParallel' in 'foreach'
+ Do not use 'AsParallel' in 'foreach'
+
+ Do Not Use Broken Cryptographic AlgorithmsNo usar algoritmos criptográficos dañados
@@ -1148,6 +1163,21 @@ La ampliación y las conversiones definidas por el usuario no se admiten con tip
{0} es un generador de números aleatorios no seguro. Use generadores de números aleatorios que sean criptográficamente seguros cuando se requiera aleatoriedad por seguridad.
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+
+ Cancel Task.Delay after Task.WhenAny completes
+ Cancel Task.Delay after Task.WhenAny completes
+
+ Do not use obsolete key derivation functionNo utilizar la función de derivación de claves obsoleta
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
index 22b8df630ee8..1bc47bd7cd33 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
@@ -1008,6 +1008,21 @@ Les conversions étendues et définies par l’utilisateur ne sont pas prises en
Utiliser un SAP de service à la place d'un SAP de compte pour appliquer un contrôle d'accès de granularité fine et une stratégie d'accès au niveau du conteneur
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+
+ Do not use 'AsParallel' in 'foreach'
+ Do not use 'AsParallel' in 'foreach'
+
+ Do Not Use Broken Cryptographic AlgorithmsNe pas utiliser d'algorithmes de chiffrement cassés
@@ -1148,6 +1163,21 @@ Les conversions étendues et définies par l’utilisateur ne sont pas prises en
{0} est un générateur de nombres aléatoires non sécurisé. Utilisez des générateurs de nombres aléatoires sécurisés de manière chiffrée quand une sélection aléatoire est nécessaire pour la sécurité.
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+
+ Cancel Task.Delay after Task.WhenAny completes
+ Cancel Task.Delay after Task.WhenAny completes
+
+ Do not use obsolete key derivation functionNe pas utiliser de fonction de dérivation de clés obsolète
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
index d08e490095a6..80484bf06877 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
@@ -1008,6 +1008,21 @@ L'ampliamento e le conversioni definite dall'utente non sono supportate con tipi
Usare la firma di accesso condiviso del service anziché quella dell'account per criteri più specifici di accesso a livello di contenitore e di controllo di accesso
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+
+ Do not use 'AsParallel' in 'foreach'
+ Do not use 'AsParallel' in 'foreach'
+
+ Do Not Use Broken Cryptographic AlgorithmsNon usare algoritmi di crittografia violati
@@ -1148,6 +1163,21 @@ L'ampliamento e le conversioni definite dall'utente non sono supportate con tipi
{0} è un generatore di numeri casuali non sicuro. Usare generatori di numeri casuali sicuri dal punto di vista della crittografia quando per motivi di sicurezza è richiesta la casualità.
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+
+ Cancel Task.Delay after Task.WhenAny completes
+ Cancel Task.Delay after Task.WhenAny completes
+
+ Do not use obsolete key derivation functionNon usare la funzione di derivazione di chiave obsoleta
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
index 097b635e9e1d..85911dff38f9 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
@@ -1008,6 +1008,21 @@ Enumerable.OfType<T> で使用されるジェネリック型チェック (
詳細に設定されたアクセス制御とコンテナーレベルのアクセス ポリシーには、アカウント SAS の代わりにサービス SAS を使用してください
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+
+ Do not use 'AsParallel' in 'foreach'
+ Do not use 'AsParallel' in 'foreach'
+
+ Do Not Use Broken Cryptographic Algorithms破られた暗号アルゴリズムを使用しない
@@ -1148,6 +1163,21 @@ Enumerable.OfType<T> で使用されるジェネリック型チェック (
{0} は安全でない乱数ジェネレーターです。セキュリティにランダム度が必要な場合に、暗号化によってセキュリティで保護された乱数ジェネレーターを使用します。
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+
+ Cancel Task.Delay after Task.WhenAny completes
+ Cancel Task.Delay after Task.WhenAny completes
+
+ Do not use obsolete key derivation function非推奨のキー派生関数を使用しないでください
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
index 07f1595a9512..c8da86954815 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
@@ -1008,6 +1008,21 @@ Enumerable.OfType<T>에서 사용하는 제네릭 형식 검사(C# 'is'
세분화된 액세스 제어와 컨테이너 수준 액세스 정책을 위해 계정 SAS가 아닌 서비스 SAS 사용
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+
+ Do not use 'AsParallel' in 'foreach'
+ Do not use 'AsParallel' in 'foreach'
+
+ Do Not Use Broken Cryptographic Algorithms손상된 암호화 알고리즘을 사용하지 마세요.
@@ -1148,6 +1163,21 @@ Enumerable.OfType<T>에서 사용하는 제네릭 형식 검사(C# 'is'
{0}은(는) 비보안 난수 생성기입니다. 보안을 위해 임의성이 필요한 경우 암호화된 보안 난수 생성기를 사용하세요.
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+
+ Cancel Task.Delay after Task.WhenAny completes
+ Cancel Task.Delay after Task.WhenAny completes
+
+ Do not use obsolete key derivation function사용되지 않는 키 파생 함수 사용 안 함
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
index 2572ec0b17a9..bfe1eef1cd12 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
@@ -1008,6 +1008,21 @@ Konwersje poszerzane i zdefiniowane przez użytkownika nie są obsługiwane w pr
Użyj sygnatury dostępu współdzielonego usługi zamiast sygnatury dostępu współdzielonego konta w celu uzyskania szczegółowej kontroli dostępu i zasad dostępu na poziomie kontenera
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+
+ Do not use 'AsParallel' in 'foreach'
+ Do not use 'AsParallel' in 'foreach'
+
+ Do Not Use Broken Cryptographic AlgorithmsNie używaj złamanych algorytmów kryptograficznych
@@ -1148,6 +1163,21 @@ Konwersje poszerzane i zdefiniowane przez użytkownika nie są obsługiwane w pr
{0} to niezabezpieczony generator liczb losowych. Użyj kryptograficznie zabezpieczonego generatora liczb losowych, gdy losowość jest wymagana ze względów bezpieczeństwa.
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+
+ Cancel Task.Delay after Task.WhenAny completes
+ Cancel Task.Delay after Task.WhenAny completes
+
+ Do not use obsolete key derivation functionNie używaj przestarzałej funkcji wyprowadzenia klucza
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf
index 97ddcd0d13ae..1f0c3fb86fc8 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf
@@ -1008,6 +1008,21 @@ As ampliação e conversões definidas pelo usuário não são compatíveis com
Usar o Serviço SAS em vez da SAS de Conta para o controle de acesso refinado e política de acesso de nível de contêiner
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+
+ Do not use 'AsParallel' in 'foreach'
+ Do not use 'AsParallel' in 'foreach'
+
+ Do Not Use Broken Cryptographic AlgorithmsNão usar algoritmos de criptografia desfeitos
@@ -1148,6 +1163,21 @@ As ampliação e conversões definidas pelo usuário não são compatíveis com
{0} é um gerador de números aleatórios não seguro. Use geradores de números aleatórios criptograficamente seguros quando a aleatoriedade for necessária para segurança.
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+
+ Cancel Task.Delay after Task.WhenAny completes
+ Cancel Task.Delay after Task.WhenAny completes
+
+ Do not use obsolete key derivation functionNão use a função de derivação de chave obsoleta
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
index 338141e13c7d..76663a37f149 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
@@ -1008,6 +1008,21 @@ Widening and user defined conversions are not supported with generic types.Используйте SAS службы вместо SAS учетной записи для детализированного контроля доступа и политики доступа на уровне контейнеров.
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+
+ Do not use 'AsParallel' in 'foreach'
+ Do not use 'AsParallel' in 'foreach'
+
+ Do Not Use Broken Cryptographic AlgorithmsНе используйте взломанные алгоритмы шифрования
@@ -1148,6 +1163,21 @@ Widening and user defined conversions are not supported with generic types.{0} является небезопасным генератором случайных чисел. Если случайные числа требуются для обеспечения безопасности, используйте криптографически безопасные генераторы случайных чисел.
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+
+ Cancel Task.Delay after Task.WhenAny completes
+ Cancel Task.Delay after Task.WhenAny completes
+
+ Do not use obsolete key derivation functionНе используйте устаревшую функцию формирования ключа.
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
index b82481f6234f..6ed1e37097ba 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
@@ -1008,6 +1008,21 @@ Genel türlerde genişletme ve kullanıcı tanımlı dönüştürmeler desteklen
Ayrıntılı erişim denetimi ve kapsayıcı düzeyinde erişim ilkesi için Hesap SAS'si yerine Hizmet SAS'sini kullanın
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+
+ Do not use 'AsParallel' in 'foreach'
+ Do not use 'AsParallel' in 'foreach'
+
+ Do Not Use Broken Cryptographic AlgorithmsBozuk Kriptografik Algoritmalar Kullanma
@@ -1148,6 +1163,21 @@ Genel türlerde genişletme ve kullanıcı tanımlı dönüştürmeler desteklen
{0}, güvenli olmayan bir rastgele sayı üreticidir. Güvenlik için rastgelelik gerekli olduğunda şifreli olarak güvenli rastgele sayı üreticileri kullanın.
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+
+ Cancel Task.Delay after Task.WhenAny completes
+ Cancel Task.Delay after Task.WhenAny completes
+
+ Do not use obsolete key derivation functionArtık kullanılmayan anahtar türetme işlevini kullanma
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf
index ba0e7cc20a7c..80b771e6b141 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf
@@ -1008,6 +1008,21 @@ Enumerable.OfType<T> 使用的泛型类型检查(C# 'is' operator/IL 'isin
使用服务 SAS 而不是帐户 SAS 实现精细访问控制和容器级访问策略
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+
+ Do not use 'AsParallel' in 'foreach'
+ Do not use 'AsParallel' in 'foreach'
+
+ Do Not Use Broken Cryptographic Algorithms不要使用损坏的加密算法
@@ -1148,6 +1163,21 @@ Enumerable.OfType<T> 使用的泛型类型检查(C# 'is' operator/IL 'isin
{0} 是不安全的随机数生成器。当需要随机性以确保安全性时,请使用加密的安全随机数生成器。
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+
+ Cancel Task.Delay after Task.WhenAny completes
+ Cancel Task.Delay after Task.WhenAny completes
+
+ Do not use obsolete key derivation function请勿使用已过时的密钥派生功能
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf
index edd8080c702f..427a7d3b0594 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf
@@ -1008,6 +1008,21 @@ Enumerable.OfType<T> 使用的一般型別檢查 (C# 'is' operator/IL 'isi
請使用服務 SAS 而非帳戶 SAS,以執行微調的存取控制和容器層級存取原則
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect. The 'foreach' statement iterates serially through the collection regardless. To parallelize LINQ operations, call 'AsParallel()' earlier in the query chain before other LINQ operators. To parallelize the loop itself, use 'Parallel.ForEach' instead.
+
+
+
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+ Using 'AsParallel()' directly in a 'foreach' loop has no effect and the loop is not parallelized
+
+
+
+ Do not use 'AsParallel' in 'foreach'
+ Do not use 'AsParallel' in 'foreach'
+
+ Do Not Use Broken Cryptographic Algorithms請勿使用損壞的密碼編譯演算法
@@ -1148,6 +1163,21 @@ Enumerable.OfType<T> 使用的一般型別檢查 (C# 'is' operator/IL 'isi
{0} 是不安全的亂數產生器。當安全性需要隨機性時,請使用密碼編譯安全性亂數產生器。
+
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+ When Task.Delay is used with Task.WhenAny to implement a timeout, the timer created by Task.Delay continues to run even after WhenAny completes, wasting resources. If your target framework supports Task.WaitAsync, use that instead as it has built-in timeout support without leaving timers running. Otherwise, pass a CancellationToken to Task.Delay that can be canceled when the operation completes.
+
+
+
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+ Using Task.WhenAny with Task.Delay may result in a timer continuing to run after the operation completes, wasting resources
+
+
+
+ Cancel Task.Delay after Task.WhenAny completes
+ Cancel Task.Delay after Task.WhenAny completes
+
+ Do not use obsolete key derivation function請勿使用已淘汰的金鑰衍生函數
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt
index 14da2a1ba4bd..9a7ec59b99a8 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt
@@ -12,13 +12,13 @@
Design: CA2210, CA1000-CA1070
Globalization: CA2101, CA1300-CA1311
Mobility: CA1600-CA1601
-Performance: HA, CA1800-CA1875
+Performance: HA, CA1800-CA1876
Security: CA2100-CA2153, CA2300-CA2330, CA3000-CA3147, CA5300-CA5405
Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2265
Naming: CA1700-CA1727
Interoperability: CA1400-CA1422
Maintainability: CA1500-CA1515
-Reliability: CA9998-CA9999, CA2000-CA2026
+Reliability: CA9998-CA9999, CA2000-CA2027
Documentation: CA1200-CA1200
# Microsoft CodeAnalysis API rules
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/WellKnownTypeNames.cs b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/WellKnownTypeNames.cs
index af724317d84f..c17ecb225358 100644
--- a/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/WellKnownTypeNames.cs
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Utilities/Compiler/WellKnownTypeNames.cs
@@ -276,6 +276,7 @@ internal static class WellKnownTypeNames
public const string SystemLinqEnumerable = "System.Linq.Enumerable";
public const string SystemLinqExpressionsExpression1 = "System.Linq.Expressions.Expression`1";
public const string SystemLinqIOrderedEnumerable1 = "System.Linq.IOrderedEnumerable`1";
+ public const string SystemLinqParallelEnumerable = "System.Linq.ParallelEnumerable";
public const string SystemLinqQueryable = "System.Linq.Queryable";
public const string SystemMarshalByRefObject = "System.MarshalByRefObject";
public const string SystemMemory1 = "System.Memory`1";
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/tests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests/Microsoft.NetCore.Analyzers/Performance/DoNotUseAsParallelInForEachLoopTests.cs b/src/Microsoft.CodeAnalysis.NetAnalyzers/tests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests/Microsoft.NetCore.Analyzers/Performance/DoNotUseAsParallelInForEachLoopTests.cs
new file mode 100644
index 000000000000..2f24cc06480e
--- /dev/null
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/tests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests/Microsoft.NetCore.Analyzers/Performance/DoNotUseAsParallelInForEachLoopTests.cs
@@ -0,0 +1,244 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.Testing;
+using Test.Utilities;
+using Xunit;
+using VerifyCS = Test.Utilities.CSharpCodeFixVerifier<
+ Microsoft.NetCore.Analyzers.Performance.DoNotUseAsParallelInForEachLoopAnalyzer,
+ Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>;
+using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier<
+ Microsoft.NetCore.Analyzers.Performance.DoNotUseAsParallelInForEachLoopAnalyzer,
+ Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>;
+
+namespace Microsoft.NetCore.Analyzers.Performance.UnitTests
+{
+ public class DoNotUseAsParallelInForEachLoopTests
+ {
+ [Fact]
+ public Task CSharp_AsParallelDirectlyInForeachLoop_ReportsDiagnostic()
+ {
+ const string code = """
+ using System.Collections.Generic;
+ using System.Linq;
+
+ public class Tests
+ {
+ public void M()
+ {
+ var list = new List { 1, 2, 3 };
+ foreach (var item in [|list.AsParallel()|])
+ {
+ }
+ }
+ }
+ """;
+
+ return VerifyCS.VerifyAnalyzerAsync(code);
+ }
+
+ [Fact]
+ public Task VB_AsParallelDirectlyInForeachLoop_ReportsDiagnostic()
+ {
+ const string code = """
+ Imports System.Collections.Generic
+ Imports System.Linq
+
+ Public Class Tests
+ Public Sub M()
+ Dim list = New List(Of Integer) From {1, 2, 3}
+ For Each item In [|list.AsParallel()|]
+ Next
+ End Sub
+ End Class
+ """;
+
+ return VerifyVB.VerifyAnalyzerAsync(code);
+ }
+
+ [Fact]
+ public Task CSharp_AsParallelWithSelectInForeachLoop_ReportsDiagnostic()
+ {
+ const string code = """
+ using System.Collections.Generic;
+ using System.Linq;
+
+ public class Tests
+ {
+ public void M()
+ {
+ var list = new List { 1, 2, 3 };
+ foreach (var item in [|list.Select(x => x * 2).AsParallel()|])
+ {
+ }
+ }
+ }
+ """;
+
+ return VerifyCS.VerifyAnalyzerAsync(code);
+ }
+
+ [Fact]
+ public Task CSharp_AsParallelWithWhereInForeachLoop_ReportsDiagnostic()
+ {
+ const string code = """
+ using System.Collections.Generic;
+ using System.Linq;
+
+ public class Tests
+ {
+ public void M()
+ {
+ var list = new List { 1, 2, 3 };
+ foreach (var item in [|list.Where(x => x > 1).AsParallel()|])
+ {
+ }
+ }
+ }
+ """;
+
+ return VerifyCS.VerifyAnalyzerAsync(code);
+ }
+
+ [Fact]
+ public Task CSharp_AsParallelEarlyInChain_NoDiagnostic()
+ {
+ const string code = """
+ using System.Collections.Generic;
+ using System.Linq;
+
+ public class Tests
+ {
+ public void M()
+ {
+ var list = new List { 1, 2, 3 };
+ var result = list.AsParallel().Select(x => x * 2).ToList();
+ }
+ }
+ """;
+
+ return VerifyCS.VerifyAnalyzerAsync(code);
+ }
+
+ [Fact]
+ public Task CSharp_AsParallelWithToList_NoDiagnostic()
+ {
+ const string code = """
+ using System.Collections.Generic;
+ using System.Linq;
+
+ public class Tests
+ {
+ public void M()
+ {
+ var list = new List { 1, 2, 3 };
+ var result = list.Select(x => x * 2).AsParallel().ToList();
+ }
+ }
+ """;
+
+ return VerifyCS.VerifyAnalyzerAsync(code);
+ }
+
+ [Fact]
+ public Task CSharp_AsParallelWithToArray_NoDiagnostic()
+ {
+ const string code = """
+ using System.Collections.Generic;
+ using System.Linq;
+
+ public class Tests
+ {
+ public void M()
+ {
+ var list = new List { 1, 2, 3 };
+ var result = list.Select(x => x * 2).AsParallel().ToArray();
+ }
+ }
+ """;
+
+ return VerifyCS.VerifyAnalyzerAsync(code);
+ }
+
+ [Fact]
+ public Task CSharp_RegularForeachWithoutAsParallel_NoDiagnostic()
+ {
+ const string code = """
+ using System.Collections.Generic;
+ using System.Linq;
+
+ public class Tests
+ {
+ public void M()
+ {
+ var list = new List { 1, 2, 3 };
+ foreach (var item in list)
+ {
+ }
+ }
+ }
+ """;
+
+ return VerifyCS.VerifyAnalyzerAsync(code);
+ }
+
+ [Fact]
+ public Task CSharp_AsParallelOnArrayDirectlyInForeachLoop_ReportsDiagnostic()
+ {
+ const string code = """
+ using System.Collections.Generic;
+ using System.Linq;
+
+ public class Tests
+ {
+ public void M()
+ {
+ var array = new int[] { 1, 2, 3 };
+ foreach (var item in [|array.AsParallel()|])
+ {
+ }
+ }
+ }
+ """;
+
+ return VerifyCS.VerifyAnalyzerAsync(code);
+ }
+
+ [Fact]
+ public Task VB_AsParallelWithSelectInForeachLoop_ReportsDiagnostic()
+ {
+ const string code = """
+ Imports System.Collections.Generic
+ Imports System.Linq
+
+ Public Class Tests
+ Public Sub M()
+ Dim list = New List(Of Integer) From {1, 2, 3}
+ For Each item In [|list.Select(Function(x) x * 2).AsParallel()|]
+ Next
+ End Sub
+ End Class
+ """;
+
+ return VerifyVB.VerifyAnalyzerAsync(code);
+ }
+
+ [Fact]
+ public Task VB_AsParallelWithToList_NoDiagnostic()
+ {
+ const string code = """
+ Imports System.Collections.Generic
+ Imports System.Linq
+
+ Public Class Tests
+ Public Sub M()
+ Dim list = New List(Of Integer) From {1, 2, 3}
+ Dim result = list.Select(Function(x) x * 2).AsParallel().ToList()
+ End Sub
+ End Class
+ """;
+
+ return VerifyVB.VerifyAnalyzerAsync(code);
+ }
+ }
+}
diff --git a/src/Microsoft.CodeAnalysis.NetAnalyzers/tests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests/Microsoft.NetCore.Analyzers/Tasks/DoNotUseNonCancelableTaskDelayWithWhenAnyTests.cs b/src/Microsoft.CodeAnalysis.NetAnalyzers/tests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests/Microsoft.NetCore.Analyzers/Tasks/DoNotUseNonCancelableTaskDelayWithWhenAnyTests.cs
new file mode 100644
index 000000000000..097305b84af0
--- /dev/null
+++ b/src/Microsoft.CodeAnalysis.NetAnalyzers/tests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests/Microsoft.NetCore.Analyzers/Tasks/DoNotUseNonCancelableTaskDelayWithWhenAnyTests.cs
@@ -0,0 +1,362 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using VerifyCS = Test.Utilities.CSharpCodeFixVerifier<
+ Microsoft.NetCore.Analyzers.Tasks.DoNotUseNonCancelableTaskDelayWithWhenAny,
+ Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>;
+using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier<
+ Microsoft.NetCore.Analyzers.Tasks.DoNotUseNonCancelableTaskDelayWithWhenAny,
+ Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>;
+
+namespace Microsoft.NetCore.Analyzers.Tasks.UnitTests
+{
+ public class DoNotUseNonCancelableTaskDelayWithWhenAnyTests
+ {
+ [Fact]
+ public async Task NoDiagnostic_TaskDelayWithCancellationToken_CSharp()
+ {
+ await VerifyCS.VerifyAnalyzerAsync("""
+ using System;
+ using System.Threading;
+ using System.Threading.Tasks;
+
+ class C
+ {
+ async Task M(CancellationToken ct)
+ {
+ var task = CreateTask();
+
+ // Should not trigger - Task.Delay has CancellationToken
+ await Task.WhenAny(task, Task.Delay(1000, ct));
+ await Task.WhenAny(Task.Delay(1000, ct), task);
+ await Task.WhenAny(Task.Delay(TimeSpan.FromSeconds(1), ct), task);
+ }
+
+ Task CreateTask() => Task.CompletedTask;
+ }
+ """);
+ }
+
+ [Fact]
+ public async Task NoDiagnostic_TaskDelayWithCancellationToken_VB()
+ {
+ await VerifyVB.VerifyAnalyzerAsync("""
+ Imports System
+ Imports System.Threading
+ Imports System.Threading.Tasks
+
+ Class C
+ Async Function M(ct As CancellationToken) As Task
+ Dim task = CreateTask()
+
+ ' Should not trigger - Task.Delay has CancellationToken
+ Await Task.WhenAny(task, Task.Delay(1000, ct))
+ Await Task.WhenAny(Task.Delay(1000, ct), task)
+ Await Task.WhenAny(Task.Delay(TimeSpan.FromSeconds(1), ct), task)
+ End Function
+
+ Function CreateTask() As Task
+ Return Task.CompletedTask
+ End Function
+ End Class
+ """);
+ }
+
+ [Fact]
+ public async Task NoDiagnostic_WhenAnyWithoutTaskDelay_CSharp()
+ {
+ await VerifyCS.VerifyAnalyzerAsync("""
+ using System.Threading.Tasks;
+
+ class C
+ {
+ async Task M()
+ {
+ var task1 = CreateTask();
+ var task2 = CreateTask();
+
+ // Should not trigger - no Task.Delay
+ await Task.WhenAny(task1, task2);
+ await Task.WhenAny(CreateTask(), CreateTask());
+ }
+
+ Task CreateTask() => Task.CompletedTask;
+ }
+ """);
+ }
+
+ [Fact]
+ public async Task Diagnostic_TaskDelayWithoutCancellationToken_CSharp()
+ {
+ await VerifyCS.VerifyAnalyzerAsync("""
+ using System;
+ using System.Threading.Tasks;
+
+ class C
+ {
+ async Task M()
+ {
+ var task = CreateTask();
+
+ // Should trigger - Task.Delay without CancellationToken
+ await Task.WhenAny(task, {|CA2027:Task.Delay(1000)|});
+ await Task.WhenAny({|CA2027:Task.Delay(1000)|}, task);
+ await Task.WhenAny({|CA2027:Task.Delay(TimeSpan.FromSeconds(1))|}, task);
+ }
+
+ Task CreateTask() => Task.CompletedTask;
+ }
+ """);
+ }
+
+ [Fact]
+ public async Task Diagnostic_TaskDelayWithoutCancellationToken_VB()
+ {
+ await VerifyVB.VerifyAnalyzerAsync("""
+ Imports System
+ Imports System.Threading.Tasks
+
+ Class C
+ Async Function M() As Task
+ Dim task = CreateTask()
+
+ ' Should trigger - Task.Delay without CancellationToken
+ Await Task.WhenAny(task, {|CA2027:Task.Delay(1000)|})
+ Await Task.WhenAny({|CA2027:Task.Delay(1000)|}, task)
+ Await Task.WhenAny({|CA2027:Task.Delay(TimeSpan.FromSeconds(1))|}, task)
+ End Function
+
+ Function CreateTask() As Task
+ Return Task.CompletedTask
+ End Function
+ End Class
+ """);
+ }
+
+ [Fact]
+ public async Task Diagnostic_MultipleTaskDelays_CSharp()
+ {
+ await VerifyCS.VerifyAnalyzerAsync("""
+ using System.Threading.Tasks;
+
+ class C
+ {
+ async Task M()
+ {
+ var task = CreateTask();
+
+ // Should trigger on both Task.Delay calls
+ await Task.WhenAny(
+ {|CA2027:Task.Delay(1000)|},
+ {|CA2027:Task.Delay(2000)|},
+ task);
+ }
+
+ Task CreateTask() => Task.CompletedTask;
+ }
+ """);
+ }
+
+ [Fact]
+ public async Task Diagnostic_MixedTaskDelays_CSharp()
+ {
+ await VerifyCS.VerifyAnalyzerAsync("""
+ using System.Threading;
+ using System.Threading.Tasks;
+
+ class C
+ {
+ async Task M(CancellationToken ct)
+ {
+ var task = CreateTask();
+
+ // Should trigger only on Task.Delay without CancellationToken
+ await Task.WhenAny(
+ {|CA2027:Task.Delay(1000)|},
+ Task.Delay(2000, ct),
+ task);
+ }
+
+ Task CreateTask() => Task.CompletedTask;
+ }
+ """);
+ }
+
+ [Fact]
+ public async Task Diagnostic_NestedInvocation_CSharp()
+ {
+ await VerifyCS.VerifyAnalyzerAsync("""
+ using System.Threading.Tasks;
+
+ class C
+ {
+ async Task M()
+ {
+ var task = CreateTask();
+
+ // Should trigger
+ var result = await Task.WhenAny(task, {|CA2027:Task.Delay(1000)|});
+ }
+
+ Task CreateTask() => Task.CompletedTask;
+ }
+ """);
+ }
+
+ [Fact]
+ public async Task NoDiagnostic_NotSystemTask_CSharp()
+ {
+ await VerifyCS.VerifyAnalyzerAsync("""
+ using System.Threading.Tasks;
+
+ namespace CustomTasks
+ {
+ public static class Task
+ {
+ public static System.Threading.Tasks.Task Delay(int milliseconds) =>
+ System.Threading.Tasks.Task.CompletedTask;
+
+ public static System.Threading.Tasks.Task WhenAny(params System.Threading.Tasks.Task[] tasks) =>
+ System.Threading.Tasks.Task.CompletedTask;
+ }
+ }
+
+ class C
+ {
+ async System.Threading.Tasks.Task M()
+ {
+ var task = CreateTask();
+
+ // Should not trigger - not System.Threading.Tasks.Task.WhenAny
+ await CustomTasks.Task.WhenAny(task, CustomTasks.Task.Delay(1000));
+ }
+
+ System.Threading.Tasks.Task CreateTask() => System.Threading.Tasks.Task.CompletedTask;
+ }
+ """);
+ }
+
+ [Fact]
+ public async Task Diagnostic_GenericTask_CSharp()
+ {
+ await VerifyCS.VerifyAnalyzerAsync("""
+ using System.Threading.Tasks;
+
+ class C
+ {
+ async Task M()
+ {
+ var task = CreateTask();
+
+ // Should trigger - works with Task too
+ await Task.WhenAny(task, {|CA2027:Task.Delay(1000)|});
+ }
+
+ Task CreateTask() => Task.FromResult(42);
+ }
+ """);
+ }
+
+ [Fact]
+ public async Task NoDiagnostic_SingleTaskDelay_CSharp()
+ {
+ await VerifyCS.VerifyAnalyzerAsync("""
+ using System.Threading.Tasks;
+
+ class C
+ {
+ async Task M()
+ {
+ // Should not trigger - single task may be used to avoid exception
+ await Task.WhenAny(Task.Delay(1000));
+ }
+ }
+ """);
+ }
+
+ [Fact]
+ public async Task Diagnostic_ExplicitArray_CSharp()
+ {
+ await VerifyCS.VerifyAnalyzerAsync("""
+ using System.Threading.Tasks;
+
+ class C
+ {
+ async Task M()
+ {
+ var task = CreateTask();
+
+ // Should trigger - explicit array creation
+ await Task.WhenAny(new[] { task, {|CA2027:Task.Delay(1000)|} });
+ }
+
+ Task CreateTask() => Task.CompletedTask;
+ }
+ """);
+ }
+
+ [Fact]
+ public async Task Diagnostic_CollectionExpression_CSharp()
+ {
+ await new VerifyCS.Test
+ {
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp12,
+ TestCode = """
+ using System.Threading.Tasks;
+
+ class C
+ {
+ async Task M()
+ {
+ var task = CreateTask();
+
+ // Should trigger - collection expression
+ await Task.WhenAny([task, {|CA2027:Task.Delay(1000)|}]);
+ }
+
+ Task CreateTask() => Task.CompletedTask;
+ }
+ """,
+ }.RunAsync();
+ }
+
+ [Fact]
+ public async Task NoDiagnostic_EmptyCollectionExpression_CSharp()
+ {
+ await new VerifyCS.Test
+ {
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp12,
+ TestCode = """
+ using System.Threading.Tasks;
+
+ class C
+ {
+ async Task M()
+ {
+ await Task.WhenAny();
+ }
+ }
+ """,
+ }.RunAsync();
+ }
+
+ [Fact]
+ public async Task NoDiagnostic_CollectionExpression_SingleTask_CSharp()
+ {
+ await new VerifyCS.Test
+ {
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp12,
+ TestCode = """
+ using System.Threading.Tasks;
+
+ class C
+ {
+ async Task M()
+ {
+ await Task.WhenAny([Task.Delay(1000)]);
+ }
+ }
+ """,
+ }.RunAsync();
+ }
+ }
+}