Q&A

Asynchronous and Parallel Programming in C#

As modern .NET applications grow increasingly reliant on concurrency to deliver responsive, scalable experiences, mastering asynchronous and parallel programming has become essential for every serious C# developer. Whether you're building server-side APIs, desktop interfaces, or data-driven services, understanding how to properly leverage async, await, and Task-based patterns is no longer optional -- it's foundational.

That's the focus of the upcoming VSLive! 2-Day Hands-On Training Seminar: Asynchronous and Parallel Programming in C#, taking place virtually June 24-25, 2025. Designed for developers working in .NET 4.8 through .NET 9, the seminar offers an immersive, code-driven dive into the techniques, tools, and best practices that power responsive UIs and high-throughput services.

Led by developer educator and .NET MVP Jeremy Clark, the workshop covers everything from basic async method usage to more advanced topics like cancellation, exception handling, and parallelization with Parallel.ForEachAsync and Channels. Attendees will learn to avoid common pitfalls, gain clarity on when and how to use ConfigureAwait(false), and explore the trade-offs between Task and ValueTask -- all through a combination of lectures, sample code, and interactive labs.

Whether you're just getting comfortable with await or looking to sharpen your understanding of concurrent patterns in .NET, this seminar is structured to give you practical knowledge you can apply immediately.

We spoke with Jeremy, known for his JeremyBytes site, to learn more about what attendees can expect from the session, what drew him to this topic, and how developers can get the most out of modern asynchronous programming.

VisualStudioMagazine: What inspired you to present a seminar on this topic?
Clark: I have been programming C# for quite a while; I remember when async/await was added to the language. Back then, I had a general idea of what await did, but I didn't have a good understanding of how it worked or what the limitations were. So I went a little deeper -- looking at the Tasks that are awaited and the various options available with Task. The result was that I had a better idea of when to await a Task (which is most of the time), but I could also use Tasks directly in the situations where I needed to go beyond what "await" offers.

"Today, asynchronous code is everywhere in the C# frameworks and libraries. It is almost impossible to program in C# without using await. I want to help other developers get a good handle on what await does, what it doesn't do, and how to write practical asynchronous code with a minimum of issues.
-- Jeremy Clark, Developer Educator

Today, asynchronous code is everywhere in the C# frameworks and libraries. It is almost impossible to program in C# without using await. I want to help other developers get a good handle on what await does, what it doesn't do, and how to write practical asynchronous code with a minimum of issues.

Inside the Seminar

What: Asynchronous and Parallel Programming in C#

When: June 24-25, 2025

Who: Jeremy Clark, Developer Educator

Why: Keep up-to-date on some of the hottest trends in the developer world to drive your career forward.

Find out more about Asynchronous and Parallel Programming in C# taking place June 24-25

What are the key benefits of using asynchronous programming in C#, and when should it be used?
A main purpose of asynchronous programming is not blocking the current thread. In a web application, one benefit is that request threads on the server are free to take more requests while our application continues to serve the current users. In a desktop application, a benefit is that the UI stays responsive (i.e., doesn't "hang") while the application does things like fetching or processing data. The concept of non-blocking operations is so important that asynchronous programming has proliferated throughout .NET frameworks and libraries. A good understanding lets us use these libraries effectively.

How does parallel programming differ from asynchronous programming, and when is each approach most effective?
Both parallel programming and asynchronous programming are examples of concurrent programming, meaning more than one operation is running at the same time.

Parallel programming is a more specific form of asynchronous programming -- running the same operation multiple times (i.e., in parallel). This can be running the same calculation across multiple CPU cores or retrieving data across multiple inbound channels. In a lot of our programs, we run only one additional thing at a time and wait for it to complete; this is usually referred to with the more generic term "asynchronous programming."

Parallel programming lets us use resources more effectively -- such as CPU cores or communication channels. There are several good options for parallel code (including Parallel.ForEachAsync and Channels). In this seminar, we'll look at what each is best at, and where we may need to do additional programming.

What are some common pitfalls developers encounter when working with async/await, and how can they be avoided?
One pitfall has to do with deciding where to await a Task. Should we await every Task? Or should we pass the Task along as is? Passing along a Task (without awaiting) is tempting since we end up with a Task further down the line anyway. But this does not always work. For example, if we do not immediately await a Task from an Entity Framework call, the data context may no longer be available when we try to access the data and our call fails.

Another pitfall is that we are used to using types such as List that are not async aware. Using one of these types in a async situation can lead to missing or incomplete data -- or worse, inconsistent results that are difficult to debug. This issue can be fixed by using an async-aware type such as BlockingCollection.

Why is ConfigureAwait(false) important, and in what scenarios should it be used?
Using ConfigureAwait(false) can optimize performance in some scenarios. Whether it is important is a bit complicated in modern C#. When using ASP.NET Core, ConfigureAwait(false) has no effect, so there is no need to use it. But if you are writing code for desktop or mobile applications (or libraries that could be used for desktop or mobile), ConfigureAwait(false) can provide small code optimization. And if you are supporting .NET Framework applications, things get even more "interesting." In this seminar, we will look at why you may or may not want to use it in your applications.

What's the best way to handle exceptions in asynchronous and parallel code to prevent application crashes?
There are different approaches to handling exceptions with asynchronous code, particularly when it comes to using Tasks. We can either let exceptions bubble up, or we can check to see if a Task has faulted. There are pros and cons to each approach, and we will look at how they fit in to our application flow.

When it comes to parallel code, an exception will often short-circuit the processes. But there are techniques that allow the parallel processes to keep running. This allows us to processes as much as we can while logging errors so that we can look at them later. Which approach we take all depends on the needs of the particular application.

When should developers use Task vs. ValueTask, and what are the trade-offs?
ValueTask is a value type, which means that it does not automatically go through the overhead of instantiating a Task object (but it can if it needs to). These can be useful in situations where a method has multiple paths -- some that are asynchronous and some that are not. In the non-asynchronous path the ValueTask can bypass the overhead of instantiating a Task. In the seminar, we'll look at some of the restrictions of ValueTask and sample code where you might use it.

What resources would you recommend for attendees to get up to speed on Asynchronous and Parallel Programming in C# and prepare for your seminar?
It's nearly impossible to be a C# developer without already working with async code in one way or another. This seminar is designed to give you a better understanding of async code, make you more comfortable with what happens when you await a Task, and also show you how to use Tasks directly. Come with what you already know, and we'll fill in the gaps throughout the seminar.

Note: Those wishing to attend the seminar can save money by registering early, according to the seminar's pricing page. "Save $150 when you register by the May 30 Early Bird deadline," said the organizer of the seminar, which is presented by the parent company of Visual Studio Magazine.

About the Author

David Ramel is an editor and writer at Converge 360.

comments powered by Disqus

Featured

  • VS Code 1.124 Focuses on Agent Autonomy and Parallel Sessions

    Microsoft's June 2026 VS Code update turns on Autopilot by default and adds background sending for agent sessions.

  • Developing Agentic Systems in .NET: From Concept to Code

    ZioNet founder Alon Fliess previews his Visual Studio Live! San Diego session on building true agentic systems in .NET -- covering the cognitive loop, MCP tool integration, multi-agent orchestration and enterprise hosting and governance with the Microsoft Agent Framework.

  • Mastering AI Development and Building AI Apps with GitHub Copilot

    Two Microsoft experts explain how GitHub Copilot is evolving from a coding assistant into a broader platform for building, customizing and testing AI-powered developer workflows.

  • VS Code 1.123 Adds Agent Session Sync, 1M Context Windows

    Microsoft released Visual Studio Code 1.123 on June 3, adding agent-focused features, larger model context support, integrated browser updates and a new delay for some automatic extension updates.

Subscribe on YouTube