# C# Performance Standards · CS-08

## Standard Metadata

- Area: C#
- Owner: Backend Steering group
- Last reviewed: 2026-09-09
- Next review due from: 2026-12-01
- Enforcement: CodeAnalysis / Rosyln Analyser / code review
- Status: Active

## Use `Any()` to determine whether an `IEnumerable<T>` is empty · CS-08.1 · **MUST**

When a method or other member returns an `IEnumerable<T>` or other collection class that does not expose a `Count` property, use the `Any()` extension method rather than `Count()` to determine whether the collection contains items. If you do use `Count()`, you risk that iterating over the entire collection might have a significant impact (such as when it really is an `IQueryable<T>` to a persistent store).

**Note**:
If you return an `IEnumerable<T>` to prevent editing from outside the owner as explained in [here](/standards/engineering/coding-standards/csharp/cs-member-design#return-an-ienumerablet-or-icollectiont-instead-of-a-concrete-collection-class) and you're developing in .NET 4.5+, consider the new read-only classes. 

**Roslyn Analyzer Rule [CA1827](https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1827)**

---

## Only use `async` for I/O operations · CS-08.2 · **SHOULD**

The usage of `async` won't automatically run something on a worker thread like `Task.Run` does. It just adds the necessary logic to allow releasing the current thread and marshal the result back on that same thread if a long-running asynchronous operation has completed. In other words, use `async` only for I/O bound operations. 

---

## Prefer `Task.Run` for CPU intensive activities · CS-08.3 · **SHOULD**

If you do need to execute a CPU bound operation, use `Task.Run` to offload the work to a thread from the Thread Pool. Just don't forget that you have to marshal the result back to your main thread manually.

---

## Beware of mixing up `await`/`async` with `Task.Wait` · CS-08.4 · **SHOULD**

`await` will not block the current thread but simply instruct to compiler to generate a state-machine. However, `Task.Wait` will block the thread and may even cause deadlocks.
