Asynchronous programming with async, await, Task in C#

C# and .NET Framework (4.5 & Core) supports asynchronous programming using some native functions, classes, and reserved keywords.

Before we see what is asynchronous programming, let's understand what is synchronous programming using the following console example.

In the above example, the LongProcess() method is some long-running task such as reading a file from the server, calling a web API that returns a large amount of data or uploading or downloading a big file. It takes a little longer time to execute ( Thread.Sleep(4000) holds it for 4 seconds just to show long execution time). The ShortProcess() is a simple method that gets executed after the LongProcess() method.

The above program executes synchronously. It means execution starts from the Main() method wherein it first executes the LongProcess() method and then ShortProcess() method. During the execution, an application gets blocked and becomes unresponsive (You can see this in Windows-based applications mainly). This is called synchronous programming where execution does not go to next line until the current line executed completely.

What is Asynchronous Programming?

In asynchronous programming, the code gets executed in a thread without having to wait for an I/O-bound or long-running task to finish. For example, in the asynchronous programming model, the LongProcess() method will be executed in a separate thread from the thread pool, and the main application thread will continue to execute the next statement.

Microsoft recommends Task-based Asynchronous Pattern  to implement asynchronous programming in the .NET Framework or .NET Core applications using async , await keywords and Task or Task<TResult> class.

Now let's rewrite the above example in asynchronous pattern using async keyword.

In the above example, the Main() method is marked by the async keyword, and the return type is Task . The async keyword marks the method as asynchronous. Note that all the methods in the method chain must be async in order to implement asynchronous programming. So, the Main() method must be async to make child methods asynchronous.

The LongProcess() method is also marked with the async keyword which makes it asynchronous. The await Task.Delay(4000); holds the thread execute for 4 seconds.

Now, the program starts executing from the async Main() method in the main application thread. The async LongProcess() method gets executed in a separate thread and the main application thread continues execution of the next statement which calls ShortProcess() method and does not wait for the LongProcess() to complete.

async, await, and Task

Use async along with await and Task if the async method returns a value back to the calling code. We used only the async keyword in the above program to demonstrate the simple asynchronous void method.

The await keyword waits for the async method until it returns a value. So the main application thread stops there until it receives a return value.

The Task class represents an asynchronous operation and Task<TResult> generic class represents an operation that can return a value. In the above example, we used await Task.Delay(4000) that started async operation that sleeps for 4 seconds and await holds a thread until 4 seconds.

The following demonstrates the async method that returns a value.

In the above example, in the static async Task<int> LongProcess() method, Task<int> is used to indicate the return value type int. int val = await result; will stop the main thread there until it gets the return value populated in the result. Once get the value in the result variable, it then automatically assigns an integer to val .

An async method should return void ,  Task , or  Task<TResult> , where TResult is the return type of the async method. Returning void is normally used for event handlers. The async keyword allows us to use the await keyword within the method so that we can wait for the asynchronous method to complete for other methods which are dependent on the return value.

If you have multiple async methods that return the values then you can use await for all methods just before you want to use the return value in further steps.

In the above program, we do await result1 and await result2 just before we need to pass the return value to another method.

Thus, you can use async , await, and Task to implement asynchronous programming in .NET Framework or .NET Core using C#.

  • How to get the sizeof a datatype in C#?
  • Difference between String and StringBuilder in C#
  • Static vs Singleton in C#
  • Difference between == and Equals() Method in C#
  • How to loop through an enum in C#?
  • Generate Random Numbers in C#
  • Difference between Two Dates in C#
  • Convert int to enum in C#
  • BigInteger Data Type in C#
  • Convert String to Enum in C#
  • Convert an Object to JSON in C#
  • Convert JSON String to Object in C#
  • DateTime Formats in C#
  • How to convert date object to string in C#?
  • Compare strings in C#
  • How to count elements in C# array?
  • Difference between String and string in C#.
  • How to get a comma separated string from an array in C#?
  • Boxing and Unboxing in C#
  • How to convert string to int in C#?

task async net core

We are a team of passionate developers, educators, and technology enthusiasts who, with their combined expertise and experience, create in-depth, comprehensive, and easy to understand tutorials. We focus on a blend of theoretical explanations and practical examples to encourages hands-on learning. Learn more about us

  • Entrepreneur
  • Productivity

Pro Code Guide

Developer's Guide to Programming

Creating an Async Web API with ASP.NET Core – Detailed Guide

In this article, we will learn about the basics of async programming with its benefits in Web API, why do we need async API and also look at how to build an Async Web API with ASP.NET Core 6. We will also learn about how async Web API provides better scalability over sync Web API.

We will also learn about how asynchronous application helps us to vertical scale our Web API application. As part of this article, we will learn how to convert an ASP.NET Core Web API application into an asynchronous application using async & await keywords.

Both .NET & .NET Core applications can work asynchronously by making use of async & await keywords. Though we will look at how to apply asynchronous programming, using async and await, to ASP.NET Core Web API this will apply to other .NET applications as well. I suggest before reading this you also read my detailed article about Asynchronous Programming in .NET Core C# – using async & await

This article assumes that you have basic knowledge of C#, ASP.NET Core & how to build Web API in ASP.NET Core. For demonstrations in this article, we will be using Visual Studio Community 2022 17.0.0 with .NET 6

Table of Contents

Introduction to Async Programming

In the context of Web API, Asynchronous programming is used to improve the scalability of the application. By applying asynchronous programming using async and await there won’t be any direct performance gain in speed instead application will be able to handle more concurrent requests. There will be indirect performance gain as there will be an improvement in the average response time of the application if we are able to handle an increased number of concurrent requests.

When we deploy our Web API on IIS then each application runs in its own worker pool and this worker pool has a fixed number of worker threads that are used to handle requests from clients. When the number of concurrent requests to our application is more than the available number of worker threads then requests go to pending state till any of the active requests are complete.

Now if you want to improve this situation that requests doesn’t go into the pending state in the queue then you need to scale your application to better handle concurrent requests. There are 2 types of scaling options available i.e. vertical scaling or horizontal scaling. In horizontal scaling, you add more servers so that additional requests can be handled by different instances of applications hosted on another server.

In vertical scaling, we either improve the processing power of the available server by adding more memory\CPU etc or by improving the scalability of our application such that our application is able to better utilize the available resources and in turn can handle more concurrent requests. Asynchronous programming techniques helps us to improve the scalability of our application by using async & await.

We don’t improve the performance by applying async programming i.e. if saving a record to the database is taking 5 seconds or an external API call for Email/SMS takes 4 seconds then by implementing async we won’t be able to reduce this processing time. Instead by using async we await the response and release the thread (till we get a response) for processing of other requests in a queue.

Synchronous vs Asynchronous Request in Web API

Async Web API with ASP.NET Core

Synchronous Requests

When a request arrives on the server then gets assigned a thread for execution from the thread pool. Thread pool contains a fixed number of threads that can be configured at the start of the application but cannot be changed at runtime. So the application has to manage throughput based on the number of available threads for execution.

When a number of concurrent requests arriving on the server exceed the number of available threads then the additional requests have to wait in queue till any request which is already executing completes and that thread becomes free and available in the thread pool for execution of the next request.

This wait queue also has a limit and if the number of requests waiting in a queue exceeds the limit then users with the new requests will start getting error responses from the server i.e. service is unavailable. Additionally, if the request is pending for execution for a long time then the client code will also timeout the request and receive a timeout exception.

Now if threads are waiting for long-running tasks like database call or HTTP call then that thread is assigned to the request but not doing anything other than waiting for the task to complete i.e. thread is blocked till the task completes.

Now till this task completes we should be able to utilize this thread for other requests this is where Asynchronous Programming techniques make a difference

Asynchronous Requests

In this scenario as well there is a fixed number of threads available in the thread pool for the execution of requests that arrives on the server. Also if the number of concurrent requests that arrives on the server exceeds the number of free threads available then additional requests go into wait state in queue. The difference between asynchronous from synchronous is threads are not blocked here for long-running tasks.

When a request arrives on the server then it gets assigned a thread from the thread pool for the execution of the request. When this request executes a long-running task like database call or HTTP call or IO operation then instead of waiting for the task to complete it awaits the task response and make threads available in the thread pool for processing of the next request waiting in the queue for execution. When the task completes the thread is re-assigned from the thread pool to the request to process task response and also for further execution.

This design allows us to handle a lot more concurrent requests as we are not blocking our threads instead task response is awaited and threads are free to process other requests till the task completes.

We saw how asynchronous programming improves the overall vertical scaling of the application as with the same available resources it is possible to handle a lot more requests. Also, this makes the application responsive to the users.

Advantages of Asynchronous Programming

Improves the overall scalability of the application by ensuring that we are able to handle more requests with the same resources available on the server. This is achieved by not blocking the threads for long-running tasks and releasing threads back to the thread pool to handle other requests in the queue when these long-running tasks are executing.

Handling more concurrent requests means users won’t have to wait long for their response. This implies there will be no timeouts and also server will rarely send error responses of Service not available (503) to the users.

There will also be an indirect improvement in the performance that if we are able to handle more concurrent requests then the average response time of the server will improve i.e. the user will get a response without delay and this will also improve overall user experience with the application.

How to use async & await in ASP.NET Core

Let’s understand the usage of async & await in async Web API with ASP.NET Core

In ASP.NET Core C# we make use of async and await keywords to implement asynchronous programming. For a method to be asynchronous we have to add the async keyword in the method definition before the return type of the method. Also, it is general practice to add Async to the name of the method if that method is asynchronous.

Only adding the async keyword in the method definition doesn’t make it asynchronous you will also have to make use of await keyword within the method. If await keyword is not used in the method then it will execute like a “synchronous” method. Also adding async to the method definition make it possible to use await keyword inside the method

We have added an asynchronous method to save data to the database. When the above method is executed then it will start executing like a normal synchronous method and start its execution. await keyword before the operation for saving to the database will start a new task for saving the changes to the database and pause the method execution till this task completes.

Till this database task completes the thread will be returned to the thread pool to handle other requests in the queue. When this task completes this method will again request a thread from the thread pool for completion of the method.

Async Return Types for Web API

void – The void return type can be used in asynchronous event handlers that require a void return type. For async methods that don’t return a value use Task instead of the void as async methods that return void cannot be awaited. In this case, the caller will be fire and forget method. The caller of an async method returning void cannot catch the exceptions thrown from the method.

Task – Task is used when async methods don’t contain a return statement or that contains a return statement that does not return an operand. If this method had been synchronous then it would have returned void. The use of task return type for an async method allows the caller to await the response from the async method so that caller’s completion can be suspended till the async method has finished.

Task<TResult> – Task<TResult> is used when async methods contain a return statement that does return an operand. The use of Task<TResult> return type for an async method allows the caller to await the response from the async method so that caller’s completion can be suspended till the async method has finished.

ValueTask<TResult> – After the release of C# 7.0 it was possible for async methods to return any type that has an accessible GetAwaiter method that returns an instance of an awaiter type. In addition, the type returned from the GetAwaiter method must have the System.Runtime.CompilerServices.AsyncMethodBuilderAttribute attribute. The Task & Task<TResult> are reference types so memory allocations particularly in tight loops can impact performance so introduction on generalized async return type (starting with C# 7.0) enabled performance improvements.

IAsyncEnumerable<T> – Starting with C# 8.0, an async method may return an async stream, represented by IAsyncEnumerable<T>. An async stream provides a way to enumerate items read from a stream when elements are generated in chunks with repeated asynchronous calls.

For further details on async return types, you can refer here

Scenarios for applying Async techniques

Before implementing the asynchronous technique in your code or method ask yourself a basic question regarding that piece of code like ‘will my code execution wait for a task to complete before it can continue ?” and if the answer to this question is yes then you need to consider asynchronous technique in this scenario as instead of waiting for the task to complete we will start the task and then await the task response.

Typical scenarios for calls where we should consider implementing asynchronous techniques are Input-output based tasks like File System operations (Read/write files) or database operations (add, update, delete or inquire data) or Network-based HTTP calls to third party API (Google API, Facebook API, Maps, SMS Services, EMAIL Service, etc.)

We can even consider asynchronous techniques in CPU bound requests i.e. tasks where we require CPU time for processing. CPU bound requests can be like where there is a large collection of objects that need to be looped or some heavy calculations (like premium calculation for insurance or interest calculation for long term loans) that requires CPU time or processing of lots of data points from some time-series database logs, etc.

Implementation of Async Web API with ASP.NET Core

Overall approach for demonstration.

Here are the details of the complete approach that has been taken for this demonstration of this async Web API with ASP.NET Core

  • We will create the first ASP.NET Core Web API project for Employee service that contains an action method to return the Employee List
  • We will be using Entity Framework Core with the model first approach to get employee details from the database. EF Core supports all the async methods for operations.
  • We will add dummy data to the employee database to simulate the get action
  • We will add both synchronous & asynchronous methods to EF Core and controller for the get action to understand differences between the two and also learn how to implement asynchronous methods in Web API

Here is the quick and short video on implementing async Web API with ASP.NET Core

Let’s first create the required project of type ASP.NET Core Web API that will be used to demonstrate how to implement Async Web API with ASP.NET Core

Create ASP.NET Core Web API Project

Create a new project of type ASP.NET Core Web API as per the screenshots shown below with the name as ProCodeGuide.Samples.AsyncWebAPI

Create ASP.NET Core async Web API

Install required packages

For the demonstration of async web API with ASP.NET Core, we will be using entity framework core as its supports the async version of the methods to perform data operations.

We need to install the required entity framework packages. You run the below mentioned commands in Package Manager or install required Nuget packages from Nuget Package Manager.

Add Database Entity

We will add the database entity class for the employee under DBEntities/EmployeeEntity.cs as per the code shown below

Add Database Context

The database context class is the main class that coordinates Entity Framework operations for a given database entity class which is EmployeeEntity in this case. You need to derive the database context class from the entity framework DbContext class and specify the entities included in the Web API. This class creates a DbSet property for the Employee entity set. An entity set typically represents a database table and an entity represents a row in the table.

We will add the interface for the database context class for the employee entity under Interfaces/IApplicationDbContext.cs as per the code shown below

We will add the database context class for the employee entity under DBContext/ApplicationDbContext.cs as per the code shown below

The database table created will have the same name as the DbSet property name.

Add Connection String to appsettings.json file

Specify the SQL Server connection string in the appsettings.json file. We are using a local database (localdb) which is a lightweight version of the SQL Server Express database engine. Add below entry to appsetting.json file

Register Database Context

You need to configure the database context as a service so that you can inject this DbContext service, using dependency injection, in the controller, or in any other service classes through the constructor parameter.

We can configure the database context as a service in the program.cs file as per the code shown below

In the above code, we have also configured a configuration object to read the connection string from the appsettings.json file.

For more details on Dependency Injection, you can read my another article –

Add Migrations

To automate the migrations from the entity framework classes we need to run the “add-migration” command and to create a database from the migrations we need to run the command “update-database” in the package manager console.

Run the below-mentioned commands in the package manager console

The above commands will create the database on the database server specified in the connection string in the appsetting.json file and also create tables in the newly created database as per DbSet objects in DbContext

Now let’s add a controller for the employee entity. Since we won’t expose Database entities through the controller so will create a model first for employees and use that model in the employee controller.

Add Employee Model

Below is the class for Employee added in Models/Employee.cs

Add Employee Service with async Get Method

Instead of adding an employee repository here for simplicity I have directly injected database context in the Employee service class and made use of that application database context to implement a method to get a list of all employees from the database.

We have added an interface for employee service in Interfaces/IEmployeeService.cs as per the code shown below

We have added implementation for employee service in Services/EmployeeService.cs as per the code shown below

In the above employee service code, we have added 2 methods to get a list of all employees from the database. One function without keyword async i.e. GetEmployee will run in synchronous mode i.e. thread will be blocked till database call completes.

Another function with the async keyword in definition and await in the body i.e. GetEmployeeAsync is an asynchronous version of method Get all employees i.e. thread will not be blocked instead thread will be free and available in thread pool to handle another request till this database call completes. Once this database call completes thread will be requested from the thread pool and execution will start from where the task was awaited.

Also in the async method, we made use of ToListAsync() method from Microsoft.EntityFrameworkCore namespace which is an async version synchronous ToList() method. The asynchronous ToListAsync() method serves the purpose to execute our query in an asynchronous mode.

With async methods don’t make use of the Result() & Wait() methods as that will block the thread till the operation completes and it will be against our purpose of writing async code for IO operations.

Also, we have registered this Employee service in the dependency container so that it can be injected into the controller using the constructor. To register employee service add the below line of code in the Program.cs file.

Add Employee Controller with async Get Method

Here is the code for the Employee controller that has been added to expose the get action for all the Employees in the database. Employee Service has been injected as a constructor parameter using dependency injection. Implementation has been added by calling the methods in the employee service class.

The employee controller supports both synchronous and asynchronous action methods using the synchronous and asynchronous methods available in employee service to get the list of all employees from the database.

We have used await inside the async action method as this await keyword will help us to extract the result from the operation for which await is used. After this result is obtained it will validate this result for success or failure and after the result is validated it will continue the code execution i.e. it will execute the statement after awaited statement.

In a single async method, we can have more than one await statement. One or more await statements will depend on the logic inside the method.

So far we looked at how to create an async web API with ASP.NET Core now let’s test this code.

Let’s run and test the code

We have enabled Open API Swagger for the Web API and we will be using the same to test our actions methods of Employee Controller

After running the application code you should see below screen

ASP.NET Core async Web API

Test Synchronous Get Method

Below are the results from the synchronous implementation of getting Employees action Method (GetEmployees)

ASP.NET Core async Web API

Test Asynchronous Get Method

Below are the results from the asynchronous implementation of getting Employees action Method (GetEmployeesAsync)

ASP.NET Core async Web API

Both methods fetched the same results but will vary in performance under load conditions.

Exception Handling in async Method

In the async method, we use await and this await keyword helps to only avoid blocking of thread till the awaited operation (Task) completes and then it will call the next statement after the awaited operation has completed. So it is like a normal code execution and we can wrap the code in a try-catch block to handle exceptions.

After we run our code, the await keyword will validate the operation after we get the result from the operation, and as soon as it notices that the operation has thrown an exception then that exception will be handled and the code will continue execution inside the catch block.

We learned about how to implement async Web API with ASP.NET Core using async and await keywords. Asynchronous Web API improves the stability of the application i.e. application is able to handle more requests and indirectly improves the performance of the application as well.

We used Entity Framework Core as it supports many asynchronous functions to implement database operations for the given database entity.

If you have still not read my detailed article on Asynchronous Programming in .NET Core C# – using async & await then I recommend you read the same here

Please provide your suggestions & questions in the comments section below

You can check my other trending articles – Build Resilient Microservices (Web API) using Polly in ASP.NET Core & Microservices with ASP.NET Core 3.1 – Ultimate Detailed Guide

Download Source Code

Here you can download the complete source code for this article demonstrating how to create async Web API with ASP.NET Core

Hope you found this article useful. Please support the Author

Buy Me A Coffee

Similar Posts

Scale ASP.NET Core Application using ThreadPool

Scale ASP.NET Core Application using ThreadPool

In this article, we will learn about how to scale our ASP.NET Core applications using Threadpool. We will specifically look at how to scale ASP.NET Core Application using the ThreadPool configuration for the number of threads. It is always advisable…

ASP.NET Core Hosting on IIS on Windows

ASP.NET Core Hosting on IIS on Windows

This article will provide details about how to perform ASP.NET Core hosting on IIS for both web application and Web API. .NET Core 2.2 onwards there were significant changes in the hosting model to IIS. Prior to .NET Core 2.2…

How to open and read XML files in C# .NET 6

How to open and read XML files in C# .NET 6

In this article, we will learn about how to work with XML files in C# .NET 6 i.e. in particular how to open and read XML files in C# .NET 6. We will look at various options available in C#…

ASP.NET Core Caching Implementation

ASP.NET Core Caching Implementation

Caching is a technique in which frequently used data is added to some memory that makes a request to this data faster as there is no need to fetch this data from the database for each request. ASP.NET Core caching…

IIS Logs Fields, IIS Logs Location & Analyze IIS Logs – Ultimate Guide

IIS Logs Fields, IIS Logs Location & Analyze IIS Logs – Ultimate Guide

In this article, we will learn about details of IIS Logs i.e. what are IIS logs, what does it contain, data fields from the HTTP requests that are logged into IIS logs, IIS Logs Formats & location of IIS Logs….

Entity Framework Core in ASP.NET Core 3.1 – Getting Started

Entity Framework Core in ASP.NET Core 3.1 – Getting Started

This article will be covering in detail the implementation of Entity Framework Core in ASP.NET Core Web API. We will learn about entity framework core in detail i.e. what, how & why and see how to use it in ASP.NET…

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Save my name, email, and website in this browser for the next time I comment.

blog post image

Andrew Lock | .NET Escapades Andrew Lock

  • ASP.NET Core
  • Dependency Injection
  • Configuration

Two approaches for running async tasks

Running async tasks on app startup in ASP.NET Core - Part 2

In my previous post I described the need to run one-off asynchronous tasks on app start up. This post follows on directly from the last one, so if you haven't already, I suggest you read that one first.

In this post I show a proposed adaptation of the "run the task manually in program.cs " approach from my last post . The implementation uses a few simple interfaces and classes to encapsulate the logic of running tasks on app start up. I also show an alternative approach that uses service decoration of IServer to execute tasks before Kestrel starts.

Running asynchronous tasks on app startup

As a recap, we're trying to find a solution that allows us to execute arbitrary asynchronous tasks on app start up. These tasks should be executed before the app starts accepting requests, but may require configuration and services, so should be executed after DI configuration is complete. Examples include things like database migrations, or populating a cache.

The solution I proposed at the end of my previous post involved running the task "manually" in Program.cs , between the calls to IWebHostBuilder.Build() and IWebHost.Run() :

This approach works, but it's a bit messy. We're going to be bloating the Program.cs file with code that probably shouldn't be there, but we could easily extract that to another class. More of an issue is having to remember to invoke the task manually. If you're using the same pattern in multiple apps, then it would be nice to have this handled for you automatically.

Registering startup tasks with the DI container

The solution I'm proposing is based on the patterns used by IStartupFilter and IHostedService . These interfaces allow you to register classes with the dependency injection container which will be executed later.

First, we create a simple interface for the startup tasks:

And a convenience method for registering startup tasks with the DI container:

Finally, we add an extension method that finds all the registered IStartupTask s on app startup, runs them in order, and then starts the IWebHost :

That's all there is to it!

To see it in action, I'll use the EF Core database migration example from the previous post .

An example - async database migration

Implementing IStartupTask is very similar to implementing IStartupFilter . You can inject services from the DI container, but if you require access to Scoped services, you should inject an IServiceProvider and create a new scope manually.

Side note - this seems like something a lot of people will get wrong, so I considered automatically creating a new scope for every task in the RunWithTasksAsync extension method. That would let you directly inject scoped services into the IStartupTask . I decided against that to keep the behaviour consistent with IStartupFilter and IHostedService - I'd be interested in any thoughts people have in the comments.

The EF Core migration startup task would look something like the following:

And we'd add the startup task to the DI container in ConfigureServices() :

Finally, we need to update Program.cs to call RunWithTasksAsync() instead of Run()

This takes advantage of the async Task Main feature of C# 7.1. Overall this code is functionally equivalent to the "manual" equivalent from my last post and above , but it has a few advantages.

  • It keeps the task implementation code out of Program.cs
  • I think it's easier to understand what's happening in Program.cs - we're running startup tasks and then running the application. Most of that is due to simply moving implementation code out of Program.cs
  • It allows you to easily add extra tasks by adding them to the DI container.
  • If you don't have any tasks, the behaviour is the same as calling RunAsync()

For me, the biggest advantage is that once you have added RunWithTasksAsync() , you can easily add additional tasks by adding them to the DI container, without having to make any other changes.

Thomas Levesque recently wrote a similar post tackling the same problem, and came to a similar solution. He has a NuGet package available for the approach .

It's not entirely sunshine and roses though…

The small print - we haven't quite finished building the app yet

Other than the fact this isn't baked into the framework (so people have to customize their Program.cs classes), there's one tiny caveat I see to the approach shown above. Even though the tasks run after the IConfiguration and DI container configuration has completed, they run before the IStartupFilter s have run and the middleware pipeline has been configured.

Personally, this hasn't been a problem for me, and I can't think of any cases where it would be. None of the tasks I've written have a dependency on the IStartupFilter s having run. That doesn't mean it won't happen though.

Unfortunately, there's not an easy way round this with the current WebHost code (though that may change in 3.0 when ASP.NET Core runs as an IHostedService ). The problem is that the application is bootstrapped (by configuring the middleware pipeline and running IStartupFilter s) and started in the same function. When you call WebHost.Run() in Program.Cs , this internally calls WebHost.StartAsync which is shown below with logging and some other minor code removed for brevity:

The problem is that we want to insert code between the call to BuildApplication() and the call to Server.StartAsync() , but there's no mechanism for doing so.

I'm not sure if the solution I settled on feels hacky or elegant, but it works, and gives an even nicer experience for consumers, as they don't need to modify Program.cs …

An alternative approach by decorating IServer

The only way I could see to run async code between BuildApplication() and Server.StartAsync() is to replace the IServer implementation (Kestrel) with our own! This isn't quite as horrendous as it sounds at first - we're not really going to replace the server, we're just going to decorate it:

The TaskExecutingServer takes an instance of IServer in its constructor - this the original KestrelServer registered by ASP.NET Core. We delegate most of the IServer implementation directly to Kestrel, we just intercept the call to StartAsync and run the injected tasks first.

The difficult part of the implementation is getting the decoration working properly. As I discussed in a previous post , using decoration with the default ASP.NET Core container can be tricky. I typically use Scrutor to create decorators, but you could always do the decoration manually if you don't want to take a dependency on another library. Be sure to look at how Scrutor does it for guidance !

The extension method shown below for adding an IStartupTask does two things - it registers an IStartupTask with the DI container, and it decorates a previously-registered IServer instance (I've left out the Decorate() implementation for brevity) . If it finds that the IServer is already decorated, it skips the second step. That way you can call AddStartupTask<T>() safely any number of times:

With these two pieces of code we no longer require users to make any changes to their Program.cs file plus we execute our tasks after the application has been fully built, including IStartupFilters and the middleware pipeline.

The sequence diagram of the startup process now looks a bit like this:

Sequence diagram of startup process

That's pretty much all there is to it. It's such a small amount of code that I wasn't sure it was worth making into a library, but it's out on GitHub and NuGet nonetheless!

I decided to only write a package for the latter approach as it's so easier to consume, and Thomas Levesque already has a NuGet package available for the first approach .

In the implementation on GitHub I manually constructed the decoration (heavily borrowing from Scrutor), to avoid forcing a dependency on Scrutor. But the best approach is probably to just copy and paste the code into your own projects 🙂 and go from there!

In this post I showed two possible ways to run tasks asynchronously on app start up while blocking the actual startup process. The first approach requires modifying your Program.cs slightly, but is "safer" in that it doesn't require messing with internal implementation details like IServer . The second approach, decorating IServer , gives a better user experience, but feels more heavy-handed. I'd be interested in which approach people feel is the better one and why, so do let me know in the comments!

Popular Tags

task async net core

Stay up to the date with the latest posts!

Dot Net Tutorials

Async and Await in C#

Back to: C#.NET Tutorials For Beginners and Professionals

Async and Await in C# with Examples:

In this article, I am going to discuss how to implement Asynchronous Programming using Async and Await in C# with Examples. Please read our previous article where we discussed the basic concepts of Asynchronous and Parallel Programming .

Asynchronous Programming in C#:

Asynchronous programming allows us to have efficient applications where we do not waste resources when they are executed. In this article, we are going to discuss Asynchronous programming. Here, we will look at concepts and patterns for developing effective asynchronous applications. We will start by discussing async, await, and how we avoid freezing the UI. In the next article, we will see the use of Task, which represents a promise of a method of execution that will end in the future. We will talk about how to report Task progress, and how to cancel tasks, and we will also look at some patterns of asynchronous programming.

Async and Await Keyword in C#:

In modern C# code, in order to use asynchronous programming, we need to use async and await keywords. The idea is that if we have a method in which we want to use asynchronous programming, then we need to mark the method with the async keyword as shown in the below image.

Async and Await Operator in C#

For those asynchronous operations for which we do not want to block the execution thread i.e. the current thread, we can use the await operator as shown in the below image.

Asynchronous Programming in C#

So, when we use await operator, what we are doing is, we are freeing the current thread from having to wait for the execution of the task. In this way, we are avoiding blocking the current thread that we’re using and then that thread can be used in another task.

Async and await works in any .NET development environment like Console applications, Windows Form applications, ASP.NET Core for Web development, Blazor for interactive web applications, etc. Here, we are going to use a Console Application because it is really simple to use. But anything that we do in the Console Application will be applicable to any .NET development environment like ASP.NET Core.

Example to Understand Async and Await in C#:

Please have a look at the below example. It’s a very simple example. Inside the main method, first, we print that main method started, then we call the SomeMethod. Inside the SomeMethod, first, we print that SomeMethod started and then the thread execution is sleep for 10. After 10 seconds, it will wake up and execute the other statement inside the SomeMethod method. Then it will come back to the main method, where we called SomeMethod. And finally, it will execute the last print statement inside the main method.

When you execute the above code, you will see that after printing SomeMethod Started……, the console window is frozen for 10 seconds. This is because here we are not using asynchronous programming. One thread i.e. the Main thread is responsible for executing the code And when we call Thread.Sleep method the current thread is blocked for 10 seconds. This is a bad user experience.

Now, let us see how we can overcome this problem by using asynchronous programming. Please have a look at the below image. The Thread.Sleep() is a synchronous method. So, we have changed this to Task.Delay() which is an asynchronous method. The Task.Delay() method exactly does the same thing as Thread.Sleep() does.

And, if we want to wait for the task i.e. Task.Delay to be done, then we have to use the await operator. As we said earlier the await operator is going to release the current thread that is running from having to wait for this operation. Therefore, that thread is going to be available for all our tasks. And then after 10 seconds, the thread will be called to the place (i.e. Task.Delay()) in order to run the rest code of the SomeMethod. As we have used await keyword inside the SomeMethod, we must have to make the SomeMethod as asynchronous as using the async keyword.

It is important to realize that await does not mean that the thread will have to be blocked waiting for the operation. Await means the thread is free to go to do another thing and then he will come back when this operation (in our example Task.Dealy i.e. after 10 seconds) is done. The following example code exactly does the same thing.

Now, if you run the above code, then you will see that after printing the Some Method Started when the statement Task.Dealy() executed, it will free the current thread, and then that current thread comes and execute the rest of the code inside the main method. And after 10 seconds again thread come back to the SomeMethod and execute the rest of the code inside the SomeMethod.

So, the bottom line is if you want to have a responsive UI that does not get blocked because of long-running operations, you must use asynchronous programming.

In the next article, I am going to discuss the Task Class in C# with Examples. Here, in this article, I try to explain how to implement Asynchronous Programming using Async and Await in C# with Examples. I hope you enjoy this Async and Await in C# with Examples article.

About the Author: Pranaya Rout

Pranaya Rout has published more than 3,000 articles in his 11-year career. Pranaya Rout has very good experience with Microsoft Technologies, Including C#, VB, ASP.NET MVC, ASP.NET Web API, EF, EF Core, ADO.NET, LINQ, SQL Server, MYSQL, Oracle, ASP.NET Core, Cloud Computing, Microservices, Design Patterns and still learning new technologies.

12 thoughts on “Async and Await in C#”

Guys, Please give your valuable feedback. And also, give your suggestions about this Async and Await Operator in C# concept. If you have any better examples, you can also put them in the comment section. If you have any key points related to Async and Await Operator in C#, you can also share the same.

Interesting article

well explained. Thank you

Hi Sir, In the above code we have SomeMethod() and in that there is a line “await Task.Delay(TimeSpan.FromSeconds(10));”, as per this line the execution goes to main method to execute remaining lines of code. If suppose the remianing lines of code or logic in Main method, takes more than 10 seconds. How come the code/ threads will be handled and will SomeMethod() waits more than 10 seconds.

Please answer this qquestion.

Awesome explaination, any method that we think will do an asynchronous operation should be marked async, any time-consuming code inside the async method should be marked with await to free up thread & will come back to review if the awaited code has finished.

Can you do asynchronous operations that return data.

/*In the above code we have SomeMethod() and in that there is a line “await Task.Delay(TimeSpan.FromSeconds(10));”, as per this line the execution goes to main method to execute remaining lines of code. If suppose the remianing lines of code or logic in Main method, takes more than 10 seconds. How come the code/ threads will be handled and will SomeMethod() waits more than 10 seconds.*/ No, the SomeMethod() won’t wait for some logic inside Main Method to finish. SomeMethod() will continue just ending the 10 seconds from “await Task.Delay(TimeSpan.FromSeconds(10));”

Try this code, I changed to 3 seconds the task.delay().

class Program { static void Main(string[] args) { Console.WriteLine(“Main Method Started……”); SomeMethod();

DateTime time1 = DateTime.Now; Console.WriteLine(“Starting Loop inside Main Method”);

for(int i=1 ; i <= 10000 ; i++) { for(int j =1; j <= 10000 ; j++) Console.Write("");

} Console.WriteLine("Ending Loop inside Main Method"); DateTime time2 = DateTime.Now; TimeSpan totaltime = time2-time1; Console.WriteLine($"Loop total time : {totaltime.TotalSeconds}");

Console.WriteLine("Main Method End"); Console.ReadKey(); } public async static void SomeMethod() { Console.WriteLine("Some Method Started……"); await Task.Delay(TimeSpan.FromSeconds(3)); //Console.WriteLine("\n"); Console.WriteLine("Some Method End"); } }

The output is:

Main Method Started…… Some Method Started…… Starting Loop inside Main Method Some Method End /* This is from SomeMethod() */ Ending Loop inside Main Method Loop total time : 5.398109 Main Method End

That’s interesting post

The reason why you get that behavior is fire & forget. You are calling async void method which is not awaited so Task.Delay that you are awaiting inside method is only awaited by the SomeMethod, but SomeMethod itself is not awaited so execution is continued

Your article is very easy to read. Thanks you very much!

Well written as usual, though there is one subtle remark: The total amount of time taken to execute the program remains the same in both cases: sync vs async, provided await is used.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

ASP.NET Core Await Foreign Tasks Warning

Avoid Awaiting Foreign Tasks in ASP.NET Core: Analyzer Warning Explanation

Abstract: In this article, we discuss a warning generated by the Microsoft.VisualStudio.Threading.Analyzers when using 'await' for foreign tasks in ASP.NET Core projects.

When developing applications using ASP.NET Core, it is essential to avoid certain practices that can lead to performance issues and potential bugs. One such practice is awaiting foreign tasks, which can cause issues in the application's threading and synchronization. This article will explain the warning generated by the Microsoft.VisualStudio.Threading.Analyzers package and provide detailed context on how to avoid this issue.

What is a Foreign Task?

A foreign task is a task that is created outside of the current synchronization context. In other words, it is a task that is not created within the same thread as the one that will eventually await it. Awaiting a foreign task can lead to performance issues, deadlocks, and other synchronization problems.

The Analyzer Warning

The Microsoft.VisualStudio.Threading.Analyzers package includes an analyzer that checks for potential issues related to threading and synchronization. When it encounters a situation where a foreign task is being awaited, it generates the following warning:

How to Avoid Awaiting Foreign Tasks

To avoid awaiting foreign tasks, you should follow these best practices:

Avoid using 'Task.Run' or 'Task.Factory.StartNew' with a non-null 'TaskScheduler' argument. These methods create a new task and run it on a separate thread. If the task is long-running, it can lead to performance issues and synchronization problems. Instead, consider using 'await Task.Yield()' to create a new task with a short lifetime.

Avoid calling 'ConfigureAwait' with 'false' on a task not bound to a specific synchronization context. This method tells the task not to capture the current synchronization context, which can lead to the task being executed on a separate thread. Instead, consider using 'ConfigureAwait(true)' to ensure that the task is executed on the current synchronization context.

Consider using 'async/await' instead of 'Task.Run' or 'Task.Factory.StartNew'. The 'async/await' pattern allows you to write asynchronous code that is easier to read and maintain. It also ensures that the task is executed on the current synchronization context, which can help avoid synchronization issues.

Avoiding awaiting foreign tasks is an essential best practice when developing applications using ASP.NET Core. By following the best practices outlined in this article, you can help ensure that your application is performant, scalable, and free from synchronization issues.

  • Consuming the Task-based Asynchronous Pattern
  • Asynchronous Programming in C#
  • Task.ConfigureAwait Method

Tags: :  ASP.NET Core C# Threading Visual Studio

Latest news

  • Running Docker Containers with User-Mounted Local Folders: A Step-by-Step Guide
  • Establishing UART Communication between Fysetc E4 Board and TMC2209 Stepper Driver
  • Achieving Widget Animation Like App Store Apps: A Solution
  • Displaying Average ROC of Multiple Instruments in Pine Script: A Syntax Query
  • Can I Use Bind VPN Service in Google Play Console for App Development?
  • Bias, Jetpack Compose, and ConstraintLayout: Aligning Images and Text
  • Running 40+ Jobs Concurrently in AWS Batch without Exceeding Time Limits
  • Progress Bar Stuck at 100%: Notification Bar Download File Issue in App Storage
  • Customizing ERPNext on Frappe Cloud: Adding a Custom Field to the Salesperson Position Screen
  • Communicating with External Devices using Android Emulator: A USB Serial Cable Solution
  • Applying Permutation Arrays with Multiple Axes in NumPy
  • Sum without Groupings: Showing Sum First in Data Processing
  • Automating Notifications with Python and Selenium: A Solution
  • Obsolete Framework Cultures in System.Globalization: A Deep Dive into 'CH' Cultures
  • Creating Users with Random Text, Number, or String API Payload in Python
  • Automatic Refresh of IConfiguration in .NET 8 with Azure Key Vault
  • Strange Phenomenon with Prerender and NPM: 404 Page Timeout Redirect
  • Podman Networking Issue: Temporary Failure in Name Resolution with Compose YML
  • Troubleshooting Touch and Mouse Click Issues in WPF Applications
  • Using Pug Template with Angular Builder: Switching from browser to ESBuild
  • Inserting Data into MS Access Database using VB.NET: A Beginner's Guide
  • React Native Maps: White Screen Issue and Map Not Rendering
  • C++ Image Passing: Upgrading from MFC to WPF for Display
  • Creating a MariaDB Galera Cluster on Kubernetes (v1.28.11) with Three Separate StatefulSets
  • Combining Byte Values Examined in Memory Words using GDB
  • Creating Relationships: Table C with Foreign Keys from Table B and Table D
  • Setting Popup Placement to Target Bottom using MAUI XAML in .Net 8.0
  • Resolving Error 'Already registered:' in Hibernate
  • Installing SageMath on Windows 10 via WSL: Problem with scipy/matlab interface
  • XSLT Rendering in Chrome and Firefox: A Comparative Study
  • Using Python Concurrent Futures with vCores: Maximizing Resource Utilization
  • Automating Google Play Store Submission: An Initial Look at the API
  • Angular 18 SSR: Generating Static Routes with Standalone Bootstrap
  • Setting up a Browser Router and handling duplicate logins in React using TypeScript
  • Cherry-Picking Changes in Git: A Comprehensive Guide
  • skip navigation Telerik UI for ASP.NET Core Product Bundles DevCraft All Telerik .NET tools and Kendo UI JavaScript components in one package. Now enhanced with: NEW : Design Kits for Figma

ASP.NET Core Basics: 12 Questions and Answers for Beginners


In this blog post, we will check out 12 questions and their answers on essential topics for understanding the basic concepts of ASP.NET Core and web development with C#.

Understanding the basics of ASP.NET Core is essential for beginners, as it creates a solid foundation for developers who want to enter the world of web development with Microsoft’s .NET framework. These core concepts are the foundations upon which developers build their skills and knowledge, enabling them to create robust and scalable web applications.

By mastering the fundamentals, beginners gain a deeper understanding of modern web development principles, which include data models, object orientation and state management.

With a solid foundation in the basics of ASP.NET Core, beginners can quickly progress on their learning journey, exploring more advanced topics such as user authorization and authentication, automated testing and cloud deployment.

Additionally, a solid understanding of ASP.NET Core fundamentals allows developers to adapt to future updates and evolutions of the framework easily, ensuring they remain current and competitive in the web development market.

In this post, we will check out 12 questions and their respective answers and see practical examples and references for further studies. At the end of the post, you will know about the main topics involved in developing web applications with ASP.NET Core.

You can access the source code of the examples demonstrated in the post here: Source Code Examples .

1. What Is ASP.NET Core?

ASP.NET Core is a modern, high-performance, cross-platform web development framework for .NET.

It is an evolution of the ASP.NET platform, designed to be more modular and lightweight, and able to work on multiple platforms. ASP.NET Core allows developers to build web applications and services using the C# programming language.

Some key features of ASP.NET Core include:

Multiplatform: ASP.NET Core is compatible with Windows, macOS and Linux, allowing applications to be developed and deployed on multiple operating systems.

Modularity: The framework comprises separate modules (NuGet packages), allowing developers to include only the components necessary for their applications, which contributes to efficiency and reduces the final size of the application.

Performance: ASP.NET Core has been optimized to deliver superior performance compared to previous versions of ASP.NET. It uses techniques such as asynchronous processing to improve the scalability and responsiveness of applications.

Container support: ASP.NET Core is designed to run in containers, making it easier to deploy and scale applications in container-based environments like Docker.

Open source: ASP.NET Core is completely open source, which means that developers have access to the source code and can contribute to the development and improvement of the platform.

Visual Studio integration: Developers can use Visual Studio, Microsoft’s IDE, to efficiently develop ASP.NET Core applications, taking advantage of features such as debugging, monitoring tools and integrated source control.


  • What is ASP.NET Core?
  • ASP.NET Core Basics: ASP.NET Core Overview

2. C# Is a Typed, Compiled and Managed Language—What Does That Mean?

The C# programming language is used to develop ASP.NET Core applications and has three main characteristics:

This means that the language requires variables to have a specified data type. For example, a variable can be of integer type ( int ), floating point type ( float ), character type ( char ), among others. This helps ensure that operations performed on a variable are appropriate for the type of data it stores, reducing programming errors.

C# is a strongly typed language, which means that data types are strictly checked at compile time. This increases the security and robustness of the code, as many errors can be detected even before the program is executed, preventing simple errors such as decimal amount = "sample value"; from reaching testing and production environments.

Note that in the code above a variable called amount is being declared, which is of decimal type (decimal numeric values), but a value of type text is being assigned to it. If this code is declared in C#, the application will not even be compiled until the error is corrected.

This means that the source code written in C# is translated into machine language (executable code) by a program called a compiler. The source code is compiled into an executable file that can be run directly by the computer.

Compilation occurs in two phases:

Compilation to Common Intermediate Language (CIL) , which is an intermediate language

Just-In-Time (JIT) compilation , which translates CIL into platform-specific machine code during execution of the program

Compilation has performance benefits because compiled code is generally faster than interpreted code.

This means that the execution of C# code is controlled by a runtime environment, such as the Common Language Runtime (CLR) for .NET Framework or .NET Core Runtime for .NET Core.

The runtime environment manages memory allocation and release, exception management, thread execution and other tasks related to program execution.

Memory management includes the use of garbage collection, which automatically frees memory from unused objects, making development more convenient and safer for programmers without the need for manual memory management, although it may introduce some performance overhead.

Reference: A tour of the C# language .

3. What Does Intermediate Language (IL) Mean?

Intermediate language (IL) is the result of compiling code written in high-level .NET languages.

Like other .NET frameworks, ASP.NET Core compiles C# or VB.NET source code into IL. This IL is then just-in-time (JIT) compiled to the machine code specific to the platform it is running on.

IL code is an intermediate representation of source code that is independent of the specific hardware architecture. This allows code to run on different platforms and architectures, as long as there is a JIT compiler available to translate the IL code into executable machine code.

Therefore, when you develop an ASP.NET Core application, the C# code you write is compiled to IL and then executed on the target machine through the JIT compilation process. This provides flexibility and portability to .NET Core applications.

Reference: Managed Code .

4. What Is Object Oriented Programming (OOP)?

Object-oriented programming (OOP) is a programming paradigm that is based on the concept of “objects,” which can contain data in the form of fields (also known as attributes or properties) and code in the form of procedures (methods or functions). These objects can interact with each other.

OOP is comprised of four fundamental principles:

Abstraction: The process of identifying the essential characteristics of an object and ignoring less important details.

Encapsulation: The idea of grouping data and related methods into a single unit, which is the class, and restricting direct access to the data.

Inheritance: The ability of a class to inherit attributes and methods from another class, allowing code reuse and the creation of class hierarchies.

Polymorphism: The ability for objects from different classes to be treated similarly, allowing methods with the same signature to behave differently depending on the type of object that calls them.

In ASP.NET Core, object-oriented programming is widely used to create web applications, where classes are typically created to represent data models, services, controllers, views and other application components.

These classes interact with each other, following OOP principles, to create robust, scalable and easily maintained applications. For example, you can create classes to represent users, products, orders and services, and then use inheritance, encapsulation and polymorphism to organize and manage these objects effectively.

  • OOP in ASP.NET Core
  • ASP.NET Core Basics: Mastering Object-Oriented Programming Concepts

5. What Are Built-in Types and What Are Some Examples?

In C#, “built-in types” refer to fundamental data types built directly into the language. These types are native to the language and do not require additional definitions to be used. They are used to declare variables, define method parameters and return method values.

Below are some examples of built-in types in C#:

  • Integral numeric types:
  • int: Represents 32-bit integers.
  • long: Represents 64-bit integers.
  • Numerical types of floating point:
  • float: Represents single-precision floating-point numbers.
  • double: Represents double precision floating point numbers.
  • Character types:
  • char: Represents a single Unicode character.
  • Boolean type:
  • bool: Represents true or false values.
  • String type:
  • string: Represents a sequence of Unicode characters.
  • Object type:
  • object: It is the root of the type hierarchy in C#; all types, including built-in types, are derived from objects.

Reference: C# built-in types .

6. What Are Namespaces and What Are They Used for?

In ASP.NET Core, a namespace is a way to logically organize and group related types, such as classes, structs, interfaces, enums and others.

They are used for the following purposes:

Code organization and structuring: Namespaces help organize code into a logical and hierarchical structure, making source code easier to understand and maintain, especially in large projects.

Preventing name conflicts: Namespaces allow types to have similar names as long as they belong to different namespaces. They help avoid name conflicts in projects that use third-party libraries or frameworks, or even in internal projects with many classes.

Encapsulation and hiding of implementation details: Namespaces allow you to hide the implementation of certain types, providing a layer of encapsulation protecting the internal details of classes and providing a clean interface for consumers of the code.

Facilitate code reuse: By grouping related types into namespaces, it becomes easier to identify and reuse classes and other types in different parts of the project or across different projects.

Facilitate code distribution: Using well-defined namespaces can facilitate the distribution of software components such as libraries or frameworks, as it allows consumers to easily access the provided types without ambiguity. For example, the .NET library has namespaces such as System, System.Collections and System.IO , among others, to organize different functionalities and related types. These namespaces help structure the library and make it easier for developers to understand and use its functionality.

Reference: C# Namespaces .

7. What Are Classes and Objects, and How Do They Relate to Each Other?

Classes and objects are fundamental concepts for implementing object-oriented systems.

Class is a blueprint or template for creating objects. It defines the properties (attributes) and behaviors (methods) that the objects of the class will have. We can say that the class is like the construction blueprint for a house, defining the characteristics and methods that operate on encapsulated data for the object.

Example of implementing a class:

Object is an instance of a class, representing a specific class instance with its unique data and state.

Objects are created based on the structure defined by the class, interacting with other objects and performing actions based on the methods defined by the class. This way we can say that if the class is the house plan, the object is the house already built.

Below is an example of an object created from the User class:

Relationship Between the Two

Classes and objects work together to enable the creation and manipulation of data in an organized and efficient manner within object-oriented programming paradigms.

While classes define the structure and behavior of objects, objects are instances of classes, which are created based on the model provided by the class.

Reference: C# classes .

8. What Are Access Modifiers?

Access modifiers are keywords used to restrict or not access a member or type, which include classes, methods, variables and others. Below are six types of access modifiers in C#:

public : Members marked as public are accessible from anywhere, both inside and outside the class in which they are defined.

private : Members marked as private are accessible only within the class in which they are defined. They cannot be accessed by code outside the class, including subclasses.

protected : Members marked as protected are accessible within the class in which they are defined and also in subclasses of that class. However, they are not accessible outside the inheritance hierarchy.

internal : Members marked as internal are accessible within the same assembly (compilation unit) in which they are defined. This means that other files in the same project can access these members, but they cannot be accessed from outside the assembly.

protected internal : It is a combination of the protected and internal modifiers. Internal protected members are accessible within the same assembly in which they are defined and also in subclasses, regardless of the assembly.

private protected : This modifier allows access to members only within the same assembly and within derived classes in the same assembly. In other words, it is more restrictive than protected internal , as it does not allow access to subclasses outside the same assembly.

Reference: Access modifiers .

9. What Are Interfaces and Abstract Classes and What Are the Differences Between Them?

Interfaces and abstract classes are key concepts in object-oriented programming that allow you to define structures for classes and objects.

An interface is a structure that contains declarations of methods, properties, events or indexers that a class or struct can implement.

Interfaces are used to define common behaviors that different classes can share, regardless of inheritance.

Abstract Classes

An abstract class is a class that cannot be instantiated by itself. It needs to be derived by other classes.

It can contain abstract methods (methods without implementation) and concrete methods (with implementation).

Abstract classes are used to provide a common structure for their subclasses. They can contain common states and behaviors shared by their subclasses. Subclasses must implement all of the abstract methods of the abstract class or they must themselves be declared as abstract classes.


Interfaces cannot be instantiated, only implemented by classes, while abstract classes can contain constructors and therefore can have instances, but the abstract class itself cannot be instantiated directly.

Interfaces can only contain the signature of methods, without implementation, while abstract classes can contain abstract methods (without implementation) and concrete methods (with implementation).

  • Abstract class

10. What Is a Sealed Class and When Is It Used?

In C#, a sealed class is a class that cannot be inherited. It is designed to prevent other classes from inheriting from it.

Sealed classes are useful in several situations where it is desirable to ensure that a class is not inherited. Below are some scenarios where a sealed class is useful.

Completed implementation: When the implementation of a class is complete and is not expected to be extended or modified.

Implementation safety: So that certain class members are not overridden in derived classes. By marking the class as sealed, it is possible to protect certain aspects of the class’s implementation.

Performance: In some situations, marking a class as sealed can allow performance optimizations by the compiler, as it knows that there is no need to consider the possibility of inheritance and member replacement.

Immutable data modeling: In some situations, there may be classes that represent immutable data, where it does not make sense to extend or modify the class. Marking these classes as sealed can help keep them immutable.

Reference: Sealed class .

11. What Are Relational Databases? What Are Some Well-known Examples?

Relational databases are database management systems (DBMSs) that structure and organize data into tables that are related to each other. These databases use the relational model, where data is stored in tables consisting of rows and columns. Primary and foreign keys define the relationships between these tables.

In the context of ASP.NET Core, we can identify some well-known examples of relational databases:

SQL Server: Developed by Microsoft, SQL Server is a very popular relational DBMS widely used in ASP.NET Core applications. It provides advanced data management, security and performance features.

MySQL: MySQL is a widely used open-source relational DBMS. It is known for its reliability, scalability and performance, making it a popular choice for ASP.NET Core applications.

PostgreSQL: PostgreSQL is another open-source relational DBMS with a strong reputation for being robust, reliable and highly extensible. It is often chosen for applications that require advanced data manipulation and transaction support capabilities.

SQLite: SQLite is a relational database library that operates without a separate database server. It is a popular choice for ASP.NET Core applications that require an embedded database, as it does not require separate server configuration and is easy to deploy. Due to its simplicity, it is widely used in mobile applications.

Oracle Database: Developed by Oracle Corporation, the Oracle Database is one of the oldest and most widely used DBMSs. It is known for its scalability, performance and advanced features, making it a common choice for large enterprise ASP.NET Core applications.

Reference: What is a relational database?

12. What Are Web APIs and What Resources Are Available in ASP.NET Core to Work with Them?

Web Application Programming Interfaces (APIs) are sets of protocols and tools for building software applications that interact with each other on the internet.

They allow different systems to communicate and share data efficiently and securely. Web APIs are widely used to integrate systems, provide services and enable communication between different applications and devices.

In the context of ASP.NET Core, there are several features available for working with Web APIs:

  • ASP.NET Core MVC: ASP.NET Core MVC (Model-View-Controller) is a powerful framework for building web applications and APIs. It provides complete support for developing and consuming web APIs using RESTful standards. MVC controllers can be used to define API endpoints and handle HTTP requests.
  • ASP.NET Core Web API: ASP.NET Core Web API is a specific framework for creating HTTP APIs. It offers built-in support for routing, JSON serialization, versioning, middleware and other features needed to build complete, high-quality RESTful APIs.
  • Flexible routing: ASP.NET Core offers a flexible routing system that allows you to define custom route patterns to map HTTP requests to the appropriate control methods. This simplifies the configuration of API endpoints with meaningful, user-friendly URIs and provides capabilities for versioning.
  • JSON serialization: ASP.NET Core has built-in support for serialization and deserialization of JSON objects. This facilitates communication between clients and servers that exchange data in JSON format, widely used in APIs and web systems.
  • Middleware: The ASP.NET Core middleware pipeline provides a flexible way to add request and response processing functionality to an API. This includes middleware for authentication, authorization, logging and compression, among others.
  • Swagger/OpenAPI: ASP.NET Core supports integration with Swagger/OpenAPI, which is a tool for documenting APIs in an automated way. It automatically generates interactive documentation for the APIs, which is extremely useful for developers consuming the API to understand how to use it correctly.

Reference: APIs with ASP.NET Core .

Investing time and effort into understanding the fundamentals of ASP.NET Core is essential for beginners who want to build a successful career as web developers.

In this post, we covered 12 questions and their answers on the main topics involving programming in systems developed in ASP.NET Core.

By understanding the concepts covered, you will be able to feel confident in creating scalable applications using object-oriented principles and the valuable features of C# and ASP.NET Core.


Assis Zang is a software developer from Brazil, developing in the .NET platform since 2017. In his free time, he enjoys playing video games and reading good books. You can follow him at: LinkedIn  and Github .

Related Posts core basics: documenting apis, clean code—a practical introduction in core, new in .net 8: core identity and how to implement it, all articles.

  • ASP.NET Core
  • Blazor Desktop/.NET MAUI
  • Design Systems
  • Document Processing
  • Accessibility

task async net core

Latest Stories in Your Inbox

Subscribe to be the first to get our expert-written articles and tutorials for developers!

All fields are required

Loading animation

Progress collects the Personal Information set out in our Privacy Policy and the Supplemental Privacy notice for residents of California and other US States and uses it for the purposes stated in that policy.

You can also ask us not to share your Personal Information to third parties here: Do Not Sell or Share My Info

By submitting this form, I understand and acknowledge my data will be processed in accordance with Progress' Privacy Policy .

I agree to receive email communications from Progress Software or its Partners , containing information about Progress Software’s products. I understand I may opt out from marketing communication at any time here or through the opt out option placed in the e-mail communication received.

By submitting this form, you understand and agree that your personal data will be processed by Progress Software or its Partners as described in our Privacy Policy . You may opt out from marketing communication at any time here or through the opt out option placed in the e-mail communication sent by us or our Partners.

We see that you have already chosen to receive marketing materials from us. If you wish to change this at any time you may do so by clicking here .

Thank you for your continued interest in Progress. Based on either your previous activity on our websites or our ongoing relationship, we will keep you updated on our products, solutions, services, company news and events. If you decide that you want to be removed from our mailing lists at any time, you can change your contact preferences by clicking here .

Code Maze

  • Blazor WASM 🔥
  • ASP.NET Core Series
  • GraphQL ASP.NET Core
  • ASP.NET Core MVC Series
  • Testing ASP.NET Core Applications
  • EF Core Series
  • HttpClient with ASP.NET Core
  • Azure with ASP.NET Core
  • ASP.NET Core Identity Series
  • IdentityServer4, OAuth, OIDC Series
  • Angular with ASP.NET Core Identity
  • Blazor WebAssembly
  • .NET Collections
  • SOLID Principles in C#
  • ASP.NET Core Web API Best Practices
  • Top REST API Best Practices
  • Angular Development Best Practices
  • 10 Things You Should Avoid in Your ASP.NET Core Controllers
  • C# Back to Basics
  • C# Intermediate
  • Design Patterns in C#
  • Sorting Algorithms in C#
  • Docker Series
  • Angular Series
  • Angular Material Series
  • HTTP Series
  • Our Editors
  • Leave Us a Review
  • Code Maze Reviews

Select Page

Generate Images Using OpenAI in an ASP.NET Core Application

Posted by Muhammed Saleem | Jul 15, 2024 | 0

Generate Images Using OpenAI in an ASP.NET Core Application

Want to build great APIs? Or become even better at it? Check our Ultimate ASP.NET Core Web API program and learn how to create a full production-ready ASP.NET Core API using only the latest .NET technologies. Bonus materials (Security book, Docker book, and other bonus files) are included in the Premium package!

In this article, we are going to explore how to generate images in an ASP.NET Core application using OpenAI.

Let’s get going.

Introduction to OpenAI Models

OpenAI has developed a range of specialized AI models, of which the GPT (Generative Pre-trained Transformer) series lays the groundwork for numerous natural language processing applications . Codex takes this further by focusing on code generation and comprehension, powering tools like GitHub Copilot to assist programmers. Additionally, the CLIP model can connect images with textual descriptions, enhancing the interaction between visual and textual data.

Become a patron at Patreon!

OpenAI’s DALL·E series has pioneered the creation of images from text, allowing us to turn written descriptions into detailed visuals . The original DALL·E model blended language comprehension with image generation, producing everything from realistic to fantastical images. DALL·E 2 improved upon this with higher quality, more consistent images, and the capability for subtle image modifications. DALL·E 3   has advanced the technology further , offering greater flexibility and the ability to mimic diverse artistic styles.

Generate Images Using OpenAI in ASP.NET Core

Let’s take a look at how to generate images in an ASP.NET Core application using the OpenAI image generation models.

To integrate OpenAI into our application, we could either sign up for an OpenAI subscription and use the APIs directly or use a cloud-hosted OpenAI instance such as the Azure OpenAI Service. By using Azure OpenAI Service, we can access the OpenAI’s advanced language models through a REST API . We can also access the service through SDKs or web-based interfaces in the Azure OpenAI Studio, which is a unified platform for developing and deploying generative AI apps.

In this article, we’ll use the Azure OpenAI Service. However, all the examples will work well even if we use the OpenAI APIs directly. The only difference is the authentication mechanism. While using the OpenAI service directly, we only need to provide the API key, whereas while using the Azure OpenAI, we need to provide an endpoint URL as well .

Setup Azure OpenAI Service

To set up the Azure OpenAI service, we must first have an Azure account with a valid subscription. 

Then we need to fill out the Azure OpenAI access form , after which it may take a few hours to be granted access. Due to high demand, continuous improvements, and responsible AI practices, Azure OpenAI access is currently limited. Priority is given to current Microsoft partners and users with low-risk applications committed to responsible use. Microsoft outlines the specific requirements in the application form and is working on responsibly broadening access. 

Once we’re given access, we can create a new OpenAI resource from the portal:

Create Azure OpenAI

After providing the required fields, such as the Subscription , Resource Group , Region , and Name , and selecting a Pricing Tier , we can proceed to create a new OpenAI resource.

Once the resource is created, let’s copy the Endpoint and Key from its Keys and Endpoint  blade and store it safely:

OpenAI Keys and Endpoints

We will be using this key and endpoint in our API application.

Deploy the DALL·E 3 Model

The next step is to deploy a model in Azure OpenAI Studio. In order to generate text or images using Azure OpenAI, we need to deploy the corresponding model in Azure OpenAI Studio and use it in our application.

First, let’s sign in to Azure OpenAI Studio and select the subscription and OpenAI resource that we want to use. After that, let’s navigate to the Deployments area and click on Create new deployment :

Creating an OpenAI model deployment

In the Deploy model popup, let’s select a model, version, and deployment type:

Deploy an OpenAI model

For image generation, we’ve chosen the dall-e-3 model, Auto-update to the default model version, and Standard deployment type. We’ve also provided a unique Deployment name  and left the advanced settings as they are.

After clicking on create, it will deploy the model, a process that could take a couple of minutes. Once the deployment is successful, we can use the provided endpoint in our application to make API calls.

Remember that when calling the model via the API, we use the deployment name that we have provided and not the model name. This is a key difference between using OpenAI directly and using Azure OpenAI .

Create and Configure an ASP.NET Core Application

Now let’s configure an ASP.NET Core Web API application with Azure OpenAI support. 

First, let’s create an ASP.NET Core Web API application, using either the Visual Studio templates or the dotnet new webapi command.

After that, let’s add the Azure.AI.OpenAI NuGet package:

Install-Package Azure.AI.OpenAI

Then let’s configure the OpenAIClient service in the Program class:

Notice that we are reading the configuration values corresponding to the OpenAI endpoint and API key and passing those.

So let’s make sure we add those configuration values in the AppSettings file. Additionally, let’s add the deployment name that we provided earlier as well:

With this, we have configured the OpenAI client in our application.

Implement the Image Generation Logic Using OpenAI

Next, let’s implement a service with image generation capability.

First, let’s define the IOpenAIService interface:

After that, let’s create the OpenAIService class and implement our new interface:

The service class encapsulates the logic for generating an image using the OpenAI API. It takes in the ImageGenerationApiModel parameter, creates an ImageGenerationOptions object, calls the API to generate the image, and returns the URL of the generated image.

Let’s define the ImageGenerationApiModel class as well:

Finally, let’s implement an API endpoint to expose this capability in a new ImageGeneratorController class:

Here we define a POST endpoint that takes the image generation options as a parameter and returns the generated image URL. The endpoint method accepts the ImageGenerationApiModel as the POST body and generates an image using the OpenAIService , then returns an object with the image URL.

DALL·E 3 Image Generation Options

While creating images with the DALL·E 3 model, we can customize the output by specifying the image size, artistic style, and quality level of the generated image, in addition to the text prompt that we provide.

For the Size parameter, DALL·E 3 supports generating images at resolutions of 1024x1024 , 1024x1792 , or 1792x1024 . The DALL·E 2 model is required for smaller image sizes, such as 512x512 or 256x256 . The Quality setting in DALL·E 3 allows us to choose between standard for faster and more cost-effective image creation, and hd for higher-quality images with greater detail. Of course, HD images come at a higher cost and with increased generation time.

The introduction of the Style parameter offers further customization, with vivid (the default) and natural as the current options to influence the visual aesthetics of the generated images. Due to system considerations, DALL·E 3 supports generating only one image per API call, so there is no need to set the ImageCount parameter. For multiple images, the recommended approach is to make concurrent API calls.

Create a UI App

Next, create a new ASP.NET Core Web Application with Razor Pages, either with the dotnet new razor command or by using the Visual Studio templates.

Once we set up the Razor Pages application, let’s add the HTML elements to the index.cshtml file:

Here, we added the input controls for the image generator web application, allowing users to enter a prompt, select image size, style, and quality, and generate an image based on their choices. Additionally, we have written a logic to display the generated image on the page. In case the image is not available, we show a placeholder message.

Next, let’s modify the index.cshtml.cs code-behind file:

Here we inject the IHttpClientFactory and IConfiguration into the IndexModel class. Additionally, we define properties such as Prompt , Size , Style , and Quality decorated with the [BindProperty] attribute. Remember that, these properties will have their values automatically bound to the corresponding form inputs in the Razor page. We use the  ImageUrl property to hold the generated image URL and the Message property to show the placeholder message, 

Next, let’s update the PostAsync() method. This method is executed when we submit the form on the page:

Here, first, we validate the form data. Next, we build a request object from the model properties and serialize it. After that, we use the HttpClient to send the serialized JSON data as a POST request to the API.

Once we receive the response from API, we deserialize it and update either the image URL or the error message based on the response status.

Note that we are reading the API URL from the configuration. So let’s make sure to configure it in the AppSettings file:

Finally, let’s create an ImageResponse   record for capturing the API response:

public record ImageResponse(string ImageUri);

Next, let’s add the styling for our UI App in the site.css file:

Here we define the layout and styling for the elements container , form-container , image-container , and generated-image .

After that, let’s add a code block to define the styles for the form-groups , including labels , textareas , selects , and buttons , as well as a placeholder element.

With this, our ASP.NET Core Razor Pages UI app is ready.

Run and Test the Application

Let’s run both the back-end API and the ASP.NET Core Razor Pages App together.

The API will open the Swagger UI and the Razor Pages App will open the web UI in the browser:

OpenAI image generator app

Now let’s provide a prompt and either choose the desired values for size , style, and quality, or leave the defaults as-is, and click on the Generate Image button:

Razor App with OpenAI generated image

This calls the API to generate an image using OpenAI and display it on the right side.

If we change the prompt and choose different options for size, style, and quality, the image will vary.

In this article, we learned how to generate images by integrating OpenAI image generation capabilities into an ASP.NET Core application. We started with an introduction to OpenAI and its various models, including a detailed look at the image generation models. We then navigated the process of setting up the Azure OpenAI service and creating an ASP.NET Core Web API application with the image generation logic. Finally, we created an ASP.NET Core Razor Pages App to consume the API, implementing a complete end-to-end workflow.

Leave a reply Cancel reply

Your email address will not be published. Required fields are marked *

Web API Book

Ultimate ASP.NET Core Web API - Second Edition

Check out our  Ultimate ASP.NET Core Web API – Second Edition and learn how to create a full production-ready ASP.NET Core API (.NET 8). Bonus materials (Security, Docker, and other bonus files) are included in the Premium package!

  • Artificial Intelligence
  • Generative AI
  • Cloud Computing
  • Data Management
  • Emerging Technology
  • Technology Industry
  • Software Development
  • Microsoft .NET
  • Development Tools
  • Open Source
  • Programming Languages
  • Enterprise Buyer’s Guides
  • Newsletters
  • Foundry Careers
  • Terms of Service
  • Privacy Policy
  • Cookie Policy
  • Copyright Notice
  • Member Preferences
  • About AdChoices
  • E-commerce Affiliate Relationships
  • Your California Privacy Rights

Our Network

  • Computerworld
  • Network World


How to use cancellation tokens in ASP.NET Core 7

Take advantage of cancellation tokens in core to allow long running operations to be cancelled gracefully and keep applications responsive..

yes no neon sign cancel buzzwords just say no red neon by sarawuth702 getty

Although ASP.NET Core 7 is the latest version of Microsoft’s open source web application development framework, it takes advantage of countless significant features from previous versions of .NET. One of these significant features is cancellation tokens, which provide a way of gracefully handling multi-threaded applications.

When working with ASP.NET Core applications, it is good practice to make long running operations (such as a database query or background process) cancelable, either after a certain length of time or upon user request, so that the application can release resources and remain responsive. Here’s where cancellation tokens come into play.

This article discusses cancellation tokens, why they are useful, and how to use them in minimal API handlers in ASP.NET Core. To work with the code examples provided in this article, you should have Visual Studio 2022 Preview installed in your system. If you don’t already have a copy, you can download Visual Studio 2022 here .

Create an ASP.NET Core 7 minimal Web API project in Visual Studio 2022

First off, let’s create an ASP.NET Core minimal API project in Visual Studio. Following these steps will create a new ASP.NET Core 7 Web API project in Visual Studio 2022 Preview:

  • Launch the Visual Studio 2022 Preview IDE.
  • Click on “Create new project.”
  • In the “Create new project” window, select “ASP.NET Core Web API” from the list of templates displayed.
  • Click Next.
  • In the “Configure your new project” window, specify the name and location for the new project.
  • Optionally check the “Place solution and project in the same directory” check box, depending on your preferences.
  • In the “Additional Information” window shown next, uncheck the check box that says “Use controllers…” since we’ll be using minimal APIs in this example. Leave the “Authentication Type” as “None” (default).
  • Ensure that the check boxes “Enable Docker,” “Configure for HTTPS,” and “Enable Open API Support” are unchecked as we won’t be using any of those features here.
  • Click Create.

We’ll use this ASP.NET Core 7 Web API project to create minimal API endpoints and work with cancellation tokens.

What are cancellation tokens? When should we use them?

A CancellationToken is a lightweight object created by a CancellationTokenSource instance. When a CancellationTokenSource is canceled, all consumers of CancellationTokens are notified accordingly. Additionally, the IsCancellationRequested property of the cancellation token instance is set to true, indicating that the CancellationTokenSource has been canceled and cancellation of the task has been requested.

You can use a CancellationToken to stop a long running operation when the user cancels a request in the web browser. In other words, using a CancellationToken can help you stop long running requests from using resources when the user has stopped or refreshed the web page.

You can use CancellationTokens to stop async tasks as well. In an async task, cancellation indicates that the task should cease performing its current activity. An async task receives a cancellation token and examines it to see if a cancellation is requested. If so, the current operation should cease immediately.

Long running requests in ASP.NET Core

When working on web applications, you might often make use of long running tasks, i.e., database calls, file handling, etc. When an object creates one or more long running operations, it should pass cancellation tokens to all of those operations. Cancellation tokens should also be passed to other internal operations.

Eventually, the object that created the long running operations may — after a time deadline is reached, or when a user stops a request — propagate a cancellation notification to these cancellation tokens. It should be noted that all long running operations must respect the cancellation request and cancel the long running operations so that resources can be released.

Listening for cancellation requests in ASP.NET Core

You can listen for cancellation requests by polling the value of the CancellationToken.IsCancellationRequested property as shown in the code snippet given below.

Another way to listen for cancellation requests is to call the ThrowIfCancellationRequested method, as shown in the code snippet given below.

And you can listen for cancellation requests by registering a callback as shown in the following code snippet.

Create a minimal API handler in ASP.NET Core

Let’s now simulate a long running request and see how cancellation works. First we’ll try a long running request without cancellation. Write the following piece of code in the Program.cs file.

When you execute this application and hit the /hello endpoint, you will see that the handler executes in its entirety even if you try to stop the request by refreshing the web browser as shown in Figure 1.

cancellation tokens 01

Figure 1: Without cancellation, the handler executes in its entirety even if the request is aborted by the user.

Use a CancellationToken in a minimal API handler

The following code listing shows how you can inject a CancellationToken into our endpoint handler and pass this token to the Task.Delay method.

Now when you execute the application and hit the /hello endpoint, refreshing the web browser before the request completes will stop the request. You’ll see from the logs that the request never completes. Instead, a TaskCancelledException will be thrown because the CancellationToken.IsCancellationRequested property will be set to true.

The exception messages will contain the trace information on the aborted request as shown in Figure 2.

cancellation tokens 02

Figure 2: When cancellation has been used in the handler code, a request that is aborted midway will not complete.

Checking cancellation state in ASP.NET Core

You might often want to know if cancellation has been requested on a cancellation token. You can check the cancellation state by examining the IsCancellationRequested property. The IsCancellationRequested property will be true (i.e., will have a boolean value of true) if cancellation has been requested on the token, false otherwise.

As mentioned above, the CancellationToken.ThrowIfCancellationRequested method will throw an OperationCanceledException if the cancellation token instance has requested cancellation.

The following code snippet illustrates how the IsCancellationRequested property can be used to check if the token has requested cancellation. If the request has been cancelled, an instance of OperationCanceledException is thrown.

Using cancellation tokens is a good practice, but it is not always recommended in your controller action methods. If the request modifies the state, you will not want such a request to be cancelled. Cancellation tokens are useful mainly for long running calls that consume significant resources, when stopping the request will not have any side effects.

Finally, for the purposes of this article, we used Task.Delay to simulate a long running operation. In its place, you can substitute any long running calls specific to your application’s requirements such as database calls, network calls, file handling operations, downloading files from the internet, and so on.

Related content

How to use fastendpoints in core, how to use refit to consume apis in core, when to use an abstract class vs. interface in c#, 6 security best practices for core.


Joydip Kanjilal is a Microsoft Most Valuable Professional (MVP) in ASP.NET, as well as a speaker and the author of several books and articles. He received the prestigious MVP award for 2007, 2008, 2009, 2010, 2011, and 2012.

He has more than 20 years of experience in IT, with more than 16 years in Microsoft .Net and related technologies. He has been selected as MSDN Featured Developer of the Fortnight (MSDN) and as Community Credit Winner several times.

He is the author of eight books and more than 500 articles. Many of his articles have been featured at Microsoft’s Official Site on ASP.Net .

He was a speaker at the Spark IT 2010 event and at the Dr. Dobb’s Conference 2014 in Bangalore. He has also worked as a judge for the Jolt Awards at Dr. Dobb's Journal. He is a regular speaker at the SSWUG Virtual Conference , which is held twice each year.

More from this author

How to implement identity authentication in minimal apis in core, how to work with dapper and sqlite in core, build an authentication handler for a minimal api in core, how to use the new minimal api features in core 8, how to implement database connection resiliency in core, speed up searches using searchvalues in .net, avoid using enums in the domain layer in c#, how to use the repr design pattern in core, most popular authors.

task async net core

Show me more

Are we thinking too small about generative ai.


How to choose the right database for your application


Beyond the usual suspects: 5 fresh data science tools to try today


How to use dbm to stash data quickly in Python


How to auto-generate Python type hints with Monkeytype


How to make HTML GUIs in Python with NiceGUI


Sponsored Links

  • Get Cisco UCS X-Series Chassis and Fabric Interconnects offer.

task async net core

  • Latest Articles
  • Top Articles
  • Posting/Update Guidelines
  • Article Help Forum

task async net core

  • View Unanswered Questions
  • View All Questions
  • View C# questions
  • View C++ questions
  • View Visual Basic questions
  • View Javascript questions
  • View Python questions
  • CodeProject.AI Server
  • All Message Boards...
  • Running a Business
  • Sales / Marketing
  • Collaboration / Beta Testing
  • Work Issues
  • Design and Architecture
  • Artificial Intelligence
  • Internet of Things
  • ATL / WTL / STL
  • Managed C++/CLI
  • Objective-C and Swift
  • System Admin
  • Hosting and Servers
  • Linux Programming
  • .NET (Core and Framework)
  • Visual Basic
  • Web Development
  • Site Bugs / Suggestions
  • Spam and Abuse Watch
  • Competitions
  • The Insider Newsletter
  • The Daily Build Newsletter
  • Newsletter archive
  • CodeProject Stuff
  • Most Valuable Professionals
  • The Lounge  
  • The CodeProject Blog
  • Where I Am: Member Photos
  • The Insider News
  • The Weird & The Wonderful
  • What is 'CodeProject'?
  • General FAQ
  • Ask a Question
  • Bugs and Suggestions

task async net core

Share Identity Bearer Tokens among ASP.NET Core Web APIs

task async net core

  • Source Codes at GitHub
  • Tag V2 for this article


This article serves as a follow-up to " Decouple ASP.NET Core Identity, Authentication and Database Engines ". In this sequel, we delve into software engineering practices that promote decoupling, making them conducive to Test-Driven Development (TDD) and rapid development of enterprise applications, in contrast to god assembly implicitly promoted by the scaffolding codes of Visual Studio project templates.

Since the early days of .NET Framework 1 and 2, Microsoft has introduced elegant architectural designs for securing application code across various program hosts—such as WinForms, WPF, Windows services, and ASP.NET (Core). As a .NET programmer, you can simply decorate relevant functions with the  AuthorizeAttribute  from various namespaces, depending on the host type. The .NET runtime then handles authentication and authorization seamlessly, leveraging appropriate configurations from app code or configuration files.

By embracing .NET Component Design and minimizing coupling between main business logic and the host, you can keep your current host’s code concise. Additionally, this approach ensures smoother migration to new hosting types in the future.

The security architecture introduced in this article has been existing in ASP.NET, well before ASP.NET Core, and the difference is ASP.NET Core has better DI/IoC.

Using the code

Comparing with the prior article, this one mainly uses "PetWebApi" as an example. The PetController was generated through some Swagger code gen upon "PetStore.yaml", and the "PetStoreClientApi" is generated using OpenApiClientGen .

Here we just need to focus on some Web API functions implemented.

Decorate Controller or Function with AuthorizeAttribute

Configurates the host program.

Now we configurate the host program for checking the right bearer tokens.

Please note, PetWebApi has no knowledge of ASP.NET Core Identity and its database, and it will just trust the bearer token produced by "Core3WebApi".

PetWebApi Trusts the Bearer Token Produced by Core3WebApi

The clients need to obtain a proper bearer token from localhost:5000 before talking to PetWebApi on localhost:6000:

Before running the test suite, launch Core3WebApi through "StartCoreWebApi.ps1" and PetWebApi through "StartPetStoreapi.ps1".

task async net core

Now you see how JWT is stateless .

And if the token is expired, the client will get the Unauthorized status code.

Shared Secret

To make such "distributed" authentication work, surely there should be some shared secret among parties of Web APIs and the primary secret is "IssuerSigningkey".

About ValidateIssuerSigningKey

According to Microsoft Learn: 

It is possible for tokens to contain the public key needed to check the signature. For example, X509Data can be hydrated into an X509Certificate, which can be used to validate the signature. In these cases it is important to validate the SigningKey that was used to validate the signature. This boolean only applies to default signing key validation. If IssuerSigningKeyValidator is set, it will be called regardless of whether this property is true or false. The default is false.

However, at least with Bearer token, even if this property is set to false, invalid or different IssuerSigningKey causes Unauthorize error. And this should obviously be the way, since the key is the primary shared secret.

Windows and Azure Cloud as well as other cloud providers provide some valet to store shared secrets. Discussing how to store such secret for production is out of the scope of this article, while there are many good references:

  • Safe storage of app secrets in development in ASP.NET Core
  • Use multiple environments in ASP.NET Core
  • Azure Key Vault configuration provider in ASP.NET Core
  • AWS Secrets Manager

Points of Interest

In "Introduction to Identity on ASP.NET Core", Microsoft suggests:

ASP.NET Core Identity adds user interface (UI) login functionality to ASP.NET Core web apps. To secure web APIs and SPAs, use one of the following:

  • Microsoft Entra ID
  • Azure Active Directory B2C  (Azure AD B2C)
  • Duende Identity Server

Microsoft actually has provided an article about using Identity with SPA:

  • How to use Identity to secure a Web API backend for SPAs

Such features have been long existing with ASP.NET Identity on .NET Framework.

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Comments and Discussions

to use this message board.
  Layout   Per page    
First Prev Next
14-May-24 3:43 14-May-24 3:43 
This is a great inspiring article. I am pretty much pleased with your good work. You put really very helpful information. Keep it up once again.
Last Visit: 31-Dec-99 18:00     Last Update: 14-Jul-24 22:43

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

task async net core

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Using Asynchronous Methods in ASP.NET MVC 4

  • 12 contributors

by Rick Anderson

This tutorial will teach you the basics of building an asynchronous ASP.NET MVC Web application using Visual Studio Express 2012 for Web , which is a free version of Microsoft Visual Studio. You can also use Visual Studio 2012 . A complete sample is provided for this tutorial on github

The ASP.NET MVC 4 Controller class in combination .NET 4.5 enables you to write asynchronous action methods that return an object of type Task<ActionResult> . The .NET Framework 4 introduced an asynchronous programming concept referred to as a Task and ASP.NET MVC 4 supports Task . Tasks are represented by the Task type and related types in the System.Threading.Tasks namespace. The .NET Framework 4.5 builds on this asynchronous support with the await and async keywords that make working with Task objects much less complex than previous asynchronous approaches. The await keyword is syntactical shorthand for indicating that a piece of code should asynchronously wait on some other piece of code. The async keyword represents a hint that you can use to mark methods as task-based asynchronous methods. The combination of await , async , and the Task object makes it much easier for you to write asynchronous code in .NET 4.5. The new model for asynchronous methods is called the Task-based Asynchronous Pattern ( TAP ). This tutorial assumes you have some familiarity with asynchronous programing using await and async keywords and the Task namespace.

For more information on the using await and async keywords and the Task namespace, see the following references.

  • Whitepaper: Asynchrony in .NET
  • Async/Await FAQ
  • Visual Studio Asynchronous Programming

How Requests Are Processed by the Thread Pool

On the web server, the .NET Framework maintains a pool of threads that are used to service ASP.NET requests. When a request arrives, a thread from the pool is dispatched to process that request. If the request is processed synchronously, the thread that processes the request is busy while the request is being processed, and that thread cannot service another request.

This might not be a problem, because the thread pool can be made large enough to accommodate many busy threads. However, the number of threads in the thread pool is limited (the default maximum for .NET 4.5 is 5,000). In large applications with high concurrency of long-running requests, all available threads might be busy. This condition is known as thread starvation. When this condition is reached, the web server queues requests. If the request queue becomes full, the web server rejects requests with an HTTP 503 status (Server Too Busy). The CLR thread pool has limitations on new thread injections. If concurrency is bursty (that is, your web site can suddenly get a large number of requests) and all available request threads are busy because of backend calls with high latency, the limited thread injection rate can make your application respond very poorly. Additionally, each new thread added to the thread pool has overhead (such as 1 MB of stack memory). A web application using synchronous methods to service high latency calls where the thread pool grows to the .NET 4.5 default maximum of 5, 000 threads would consume approximately 5 GB more memory than an application able the service the same requests using asynchronous methods and only 50 threads. When you're doing asynchronous work, you're not always using a thread. For example, when you make an asynchronous web service request, ASP.NET will not be using any threads between the async method call and the await . Using the thread pool to service requests with high latency can lead to a large memory footprint and poor utilization of the server hardware.

Processing Asynchronous Requests

In a web app that sees a large number of concurrent requests at start-up or has a bursty load (where concurrency increases suddenly), making web service calls asynchronous increases the responsiveness of the app. An asynchronous request takes the same amount of time to process as a synchronous request. If a request makes a web service call that requires two seconds to complete, the request takes two seconds whether it's performed synchronously or asynchronously. However during an asynchronous call, a thread isn't blocked from responding to other requests while it waits for the first request to complete. Therefore, asynchronous requests prevent request queuing and thread pool growth when there are many concurrent requests that invoke long-running operations.

Choosing Synchronous or Asynchronous Action Methods

This section lists guidelines for when to use synchronous or asynchronous action methods. These are just guidelines; examine each application individually to determine whether asynchronous methods help with performance.

In general, use synchronous methods for the following conditions:

  • The operations are simple or short-running.
  • Simplicity is more important than efficiency.
  • The operations are primarily CPU operations instead of operations that involve extensive disk or network overhead. Using asynchronous action methods on CPU-bound operations provides no benefits and results in more overhead.

In general, use asynchronous methods for the following conditions:

  • You're calling services that can be consumed through asynchronous methods, and you're using .NET 4.5 or higher.
  • The operations are network-bound or I/O-bound instead of CPU-bound.
  • Parallelism is more important than simplicity of code.
  • You want to provide a mechanism that lets users cancel a long-running request.
  • When the benefit of switching threads outweighs the cost of the context switch. In general, you should make a method asynchronous if the synchronous method waits on the ASP.NET request thread while doing no work. By making the call asynchronous, the ASP.NET request thread is not stalled doing no work while it waits for the web service request to complete.
  • Testing shows that the blocking operations are a bottleneck in site performance and that IIS can service more requests by using asynchronous methods for these blocking calls.

The downloadable sample shows how to use asynchronous action methods effectively. The sample provided was designed to provide a simple demonstration of asynchronous programming in ASP.NET MVC 4 using .NET 4.5. The sample is not intended to be a reference architecture for asynchronous programming in ASP.NET MVC. The sample program calls ASP.NET Web API methods which in turn call Task.Delay to simulate long-running web service calls. Most production applications will not show such obvious benefits to using asynchronous action methods.

Few applications require all action methods to be asynchronous. Often, converting a few synchronous action methods to asynchronous methods provides the best efficiency increase for the amount of work required.

The Sample Application

You can download the sample application from on the GitHub site. The repository consists of three projects:

  • Mvc4Async : The ASP.NET MVC 4 project that contains the code used in this tutorial. It makes Web API calls to the WebAPIpgw service.
  • WebAPIpgw : The ASP.NET MVC 4 Web API project that implements the Products, Gizmos and Widgets controllers. It provides the data for the WebAppAsync project and the Mvc4Async project.
  • WebAppAsync : The ASP.NET Web Forms project used in another tutorial.

The Gizmos Synchronous Action Method

The following code shows the Gizmos synchronous action method that is used to display a list of gizmos. (For this article, a gizmo is a fictional mechanical device.)

The following code shows the GetGizmos method of the gizmo service.

The GizmoService GetGizmos method passes a URI to an ASP.NET Web API HTTP service which returns a list of gizmos data. The WebAPIpgw project contains the implementation of the Web API gizmos, widget and product controllers. The following image shows the gizmos view from the sample project.


Creating an Asynchronous Gizmos Action Method

The sample uses the new async and await keywords (available in .NET 4.5 and Visual Studio 2012) to let the compiler be responsible for maintaining the complicated transformations necessary for asynchronous programming. The compiler lets you write code using the C#'s synchronous control flow constructs and the compiler automatically applies the transformations necessary to use callbacks in order to avoid blocking threads.

The following code shows the Gizmos synchronous method and the GizmosAsync asynchronous method. If your browser supports the HTML 5 <mark> element , you'll see the changes in GizmosAsync in yellow highlight.

The following changes were applied to allow the GizmosAsync to be asynchronous.

  • The method is marked with the async keyword, which tells the compiler to generate callbacks for parts of the body and to automatically create a Task<ActionResult> that is returned.
  • "Async" was appended to the method name. Appending "Async" is not required but is the convention when writing asynchronous methods.
  • The return type was changed from ActionResult to Task<ActionResult> . The return type of Task<ActionResult> represents ongoing work and provides callers of the method with a handle through which to wait for the asynchronous operation's completion. In this case, the caller is the web service. Task<ActionResult> represents ongoing work with a result of ActionResult.
  • The await keyword was applied to the web service call.
  • The asynchronous web service API was called ( GetGizmosAsync ).

Inside of the GetGizmosAsync method body another asynchronous method, GetGizmosAsync is called. GetGizmosAsync immediately returns a Task<List<Gizmo>> that will eventually complete when the data is available. Because you don't want to do anything else until you have the gizmo data, the code awaits the task (using the await keyword). You can use the await keyword only in methods annotated with the async keyword.

The await keyword does not block the thread until the task is complete. It signs up the rest of the method as a callback on the task, and immediately returns. When the awaited task eventually completes, it will invoke that callback and thus resume the execution of the method right where it left off. For more information on using the await and async keywords and the Task namespace, see the async references .

The following code shows the GetGizmos and GetGizmosAsync methods.

The asynchronous changes are similar to those made to the GizmosAsync above.

  • The method signature was annotated with the async keyword, the return type was changed to Task<List<Gizmo>> , and Async was appended to the method name.
  • The asynchronous HttpClient class is used instead of the WebClient class.
  • The await keyword was applied to the HttpClient asynchronous methods.

The following image shows the asynchronous gizmo view.


The browsers presentation of the gizmos data is identical to the view created by the synchronous call. The only difference is the asynchronous version may be more performant under heavy loads.

Performing Multiple Operations in Parallel

Asynchronous action methods have a significant advantage over synchronous methods when an action must perform several independent operations. In the sample provided, the synchronous method PWG (for Products, Widgets and Gizmos) displays the results of three web service calls to get a list of products, widgets, and gizmos. The ASP.NET Web API project that provides these services uses Task.Delay to simulate latency or slow network calls. When the delay is set to 500 milliseconds, the asynchronous PWGasync method takes a little over 500 milliseconds to complete while the synchronous PWG version takes over 1,500 milliseconds. The synchronous PWG method is shown in the following code.

The asynchronous PWGasync method is shown in the following code.

The following image shows the view returned from the PWGasync method.


Using a Cancellation Token

Asynchronous action methods returning Task<ActionResult> are cancelable, that is they take a CancellationToken parameter when one is provided with the AsyncTimeout attribute. The following code shows the GizmosCancelAsync method with a timeout of 150 milliseconds.

The following code shows the GetGizmosAsync overload, which takes a CancellationToken parameter.

In the sample application provided, selecting the Cancellation Token Demo link calls the GizmosCancelAsync method and demonstrates the cancellation of the asynchronous call.

Server Configuration for High Concurrency/High Latency Web Service Calls

To realize the benefits of an asynchronous web application, you might need to make some changes to the default server configuration. Keep the following in mind when configuring and stress testing your asynchronous web application.

Windows 7, Windows Vista and all Windows client operating systems have a maximum of 10 concurrent requests. You'll need a Windows Server operating system to see the benefits of asynchronous methods under high load.

Register .NET 4.5 with IIS from an elevated command prompt: %windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis -i See ASP.NET IIS Registration Tool (Aspnet_regiis.exe)

You might need to increase the HTTP.sys queue limit from the default value of 1,000 to 5,000. If the setting is too low, you may see HTTP.sys reject requests with a HTTP 503 status. To change the HTTP.sys queue limit:

  • Open IIS manager and navigate to the Application Pools pane.


Note in the images above, the .NET framework is listed as v4.0, even though the application pool is using .NET 4.5. To understand this discrepancy, see the following:

  • .NET Versioning and Multi-Targeting - .NET 4.5 is an in-place upgrade to .NET 4.0
  • How to set an IIS Application or AppPool to use ASP.NET 3.5 rather than 2.0
  • .NET Framework Versions and Dependencies

If your application is using web services or System.NET to communicate with a backend over HTTP you may need to increase the connectionManagement/maxconnection element. For ASP.NET applications, this is limited by the autoConfig feature to 12 times the number of CPUs. That means that on a quad-proc, you can have at most 12 * 4 = 48 concurrent connections to an IP end point. Because this is tied to autoConfig , the easiest way to increase maxconnection in an ASP.NET application is to set System.Net.ServicePointManager.DefaultConnectionLimit programmatically in the from Application_Start method in the global.asax file. See the sample download for an example.

In .NET 4.5, the default of 5000 for MaxConcurrentRequestsPerCPU should be fine.

Was this page helpful?

Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see: .

Submit and view feedback for

Additional resources

  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
  • OverflowAI GenAI features for Teams
  • OverflowAPI Train & fine-tune LLMs
  • Labs The future of collective knowledge sharing
  • About the company Visit the blog

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

How to safely call an async method in C# without await

I have an async method which returns no data:

I'm calling this from another method which returns some data:

Calling MyAsyncMethod() without awaiting it causes a " Because this call is not awaited, the current method continues to run before the call is completed " warning in visual studio. On the page for that warning it states:

You should consider suppressing the warning only if you're sure that you don't want to wait for the asynchronous call to complete and that the called method won't raise any exceptions .

I'm sure I don't want to wait for the call to complete; I don't need to or have the time to. But the call might raise exceptions.

I've stumbled into this problem a few times and I'm sure it's a common problem which must have a common solution.

How do I safely call an async method without awaiting the result?

For people suggesting that I just await the result, this is code that is responding to a web request on our web service (ASP.NET Web API). Awaiting in a UI context keeps the UI thread free, but awaiting in a web request call will wait for the Task to finish before responding to the request, thereby increasing response times with no reason.

  • async-await
  • task-parallel-library

Community's user avatar

  • 2 If you don't want to wait for the result, the only option is to ignore/suppress the warning. If you do want to wait for the result/exception then MyAsyncMethod().Wait() –  Peter Ritchie Commented Mar 20, 2013 at 12:42
  • 5 About your edit: that does not make sense to me. Say the response is sent to the client 1 sec after the request, and 2 secs later your async method throws an exception. What would you do with that exception? You cannot send it to the client, if your response is already sent. What else would you do with it? –  user743382 Commented Mar 20, 2013 at 13:02
  • 2 @Romoku Fair enough. Assuming someone looks at the log, anyway. :) –  user743382 Commented Mar 20, 2013 at 13:11
  • 4 A variation on the ASP.NET Web API scenario is a self-hosted Web API in a long-lived process (like, say, a Windows service), where a request creates a lengthy background task to do something expensive, but still wants to get a response quickly with an HTTP 202 (Accepted). –  David Rubin Commented Jun 23, 2015 at 17:44
  • 4 Why not use Task.Run() ? –  Kyle Delaney Commented Jun 29, 2017 at 17:26

13 Answers 13

If you want to get the exception "asynchronously", you could do:

This will allow you to deal with an exception on a thread other than the "main" thread. This means you don't have to "wait" for the call to MyAsyncMethod() from the thread that calls MyAsyncMethod ; but, still allows you to do something with an exception--but only if an exception occurs.

technically, you could do something similar with await :

...which would be useful if you needed to specifically use try / catch (or using ) but I find the ContinueWith to be a little more explicit because you have to know what ConfigureAwait(false) means.

Peter Ritchie's user avatar

  • 12 I turned this into an extension method on Task : public static class AsyncUtility { public static void PerformAsyncTaskWithoutAwait(this Task task, Action<Task> exceptionHandler) { var dummy = task.ContinueWith(t => exceptionHandler(t), TaskContinuationOptions.OnlyOnFaulted); } } Usage: MyAsyncMethod().PerformAsyncTaskWithoutAwait(t => log.ErrorFormat("An error occurred while calling MyAsyncMethod:\n{0}", t.Exception)); –  Mark Avenius Commented Jun 24, 2015 at 14:13
  • 11 Hey - I did not downvote, but... Can you explain your update? The call was not supposed to be awaited, so if you do it like that, then you do wait for the call, you just don't continue on the captured context... –  Bartosz Commented May 17, 2017 at 20:48
  • 56 The ContinueWith version is not the same as the try{ await }catch{} version. In the first version, everything after ContinueWith() will execute immediately. The initial task is fired and forgotten. In the second version, everything after the catch{} will execute only after the initial task is completed. The second version is equivalent to "await MyAsyncMethod().ContinueWith(t => Console.WriteLine(t.Exception), TaskContinuationOptions.OnlyOnFaulted).ConfigureAwait(fals); –  Thanasis Ioannidis Commented Oct 12, 2017 at 9:59
  • 2 I tried a test app with .ConfigureAwait(false); but it still suspends a loop. The only solution I found was to make the called method async void (so no await is required), which solution everyone considers bad. But I think it's the nicest solution for creating an independent task. –  Crouching Kitten Commented Mar 10, 2019 at 19:09
  • 7 Confirmed that the comment from Thanasis Ioannidis is best to answer the OP question. @PeterRitchie, I strongly recommend updating your accepted answer to avoid this being buried in comments. –  jrap Commented Mar 17, 2020 at 15:26

You should first consider making GetStringData an async method and have it await the task returned from MyAsyncMethod .

If you're absolutely sure that you don't need to handle exceptions from MyAsyncMethod or know when it completes, then you can do this:

BTW, this is not a "common problem". It's very rare to want to execute some code and not care whether it completes and not care whether it completes successfully.

Since you're on ASP.NET and wanting to return early, you may find my blog post on the subject useful . However, ASP.NET was not designed for this, and there's no guarantee that your code will run after the response is returned. ASP.NET will do its best to let it run, but it can't guarantee it.

So, this is a fine solution for something simple like tossing an event into a log where it doesn't really matter if you lose a few here and there. It's not a good solution for any kind of business-critical operations. In those situations, you must adopt a more complex architecture, with a persistent way to save the operations (e.g., Azure Queues, MSMQ) and a separate background process (e.g., Azure Worker Role, Win32 Service) to process them.

Stephen Cleary's user avatar

  • 8 I think you might have misunderstood. I do care if it throws exceptions and fails, but I don't want to have to await the method before returning my data. Also see my edit about the context I'm working in if that makes any difference. –  George Powell Commented Mar 20, 2013 at 13:02
  • 8 @GeorgePowell: It's very dangerous to have code running in an ASP.NET context without an active request. I have a blog post that may help you out , but without knowing more of your problem I can't say whether I'd recommend that approach or not. –  Stephen Cleary Commented Mar 20, 2013 at 13:17
  • 2 @StephenCleary I have a similar need. In my example, I have/need a batch processing engine to run in the cloud, I'll "ping" the end point to kick off batch processing, but I want to return immediately. Since pinging it gets it started, it can handle everything from there. If there are exceptions that are thrown, then they'd just be logged in my "BatchProcessLog/Error" tables... –  ganders Commented Aug 16, 2016 at 18:31
  • 16 In C#7, you can replace var _ = MyAsyncMethod(); with _ = MyAsyncMethod(); . This still avoids warning CS4014, but it makes it a bit more explicit that you're not using the variable. –  Brian Commented Jan 19, 2018 at 23:09
  • 6 I think what OP means is that he doesn't want the client (HTTP Request) to wait on whether logging something to a database succeeds. If the logging fails, sure the application should still have full control over handling that exception, but we don't need the client to wait around for the handling of that. I think what that means is that work needs to be done on a background thread. Yeah.. sucks to reserve a thread to do an async task, but it needs to be done to handle potential exceptions. –  The Muffin Man Commented Nov 24, 2020 at 17:39

The answer by Peter Ritchie was what I wanted, and Stephen Cleary's article about returning early in ASP.NET was very helpful.

As a more general problem however (not specific to an ASP.NET context) the following Console application demonstrates the usage and behavior of Peter's answer using Task.ContinueWith(...)

GetStringData() returns early without awaiting MyAsyncMethod() and exceptions thrown in MyAsyncMethod() are dealt with in OnMyAsyncMethodFailed(Task task) and not in the try / catch around GetStringData()

  • 11 Remove Console.ReadLine(); and add a little sleep/delay in MyAsyncMethod and you'll never see the exception. –  tmaj Commented Nov 23, 2016 at 22:57

I end up with this solution :

Filimindji's user avatar

This is called fire and forget, and there is an extension for that.

Consumes a task and doesn't do anything with it. Useful for fire-and-forget calls to async methods within async methods.

Install nuget package .

EDIT: There is another way I've been rather using lately:

wast's user avatar

  • 24 It doesn't do anything, it's just a trick to remove the warning. See… –  Paolo Fulgoni Commented Jun 28, 2019 at 12:25
  • Correction: It does a bunch of stuff to avoid reacting to the call that was made. –  Mauricio Gracia Gutierrez Commented Jul 22, 2021 at 17:34

Not the best practice, you should try avoiding this.

However, just to address "Call an async method in C# without await", you can execute the async method inside a Task.Run . This approach will wait until MyAsyncMethod finish.

await asynchronously unwraps the Result of your task, whereas just using Result would block until the task had completed.

If you want to wrap it in a helper class:

and call like

CharithJ's user avatar

  • 6 wouldn't MyAsyncMethod().Result just do the same thing? –  maraaaaaaaa Commented Feb 18, 2022 at 20:57

I'm late to the party here, but there's an awesome library I've been using which I haven't seen referenced in the other answers

If you need to "Fire And Forget" you call the extension method on the task.

Passing the action onException to the call ensures that you get the best of both worlds - no need to await execution and slow your users down, whilst retaining the ability to handle the exception in a graceful manner.

In your example you would use it like this:

It also gives awaitable AsyncCommands implementing ICommand out the box which is great for my MVVM Xamarin solution

Adam Diament's user avatar

  • This doesn't add confidence to it? –  Maja Stamenic Commented Aug 3, 2022 at 10:32
  • 1 The author of that post is using purposefully bad design by using Thread.Sleep inside of his BadTask instead of await Task.Delay. (I'm not sure why). In almost all normal cases, you wouldn't do this. For most use cases, this does what it says on the tin. –  Adam Diament Commented Aug 4, 2022 at 11:08
  • @AdamDiament they're using Thread.Sleep to simulate a task that does a large amount of synchronous work before await ing something (e.g. if you had to do a computationally expensive calculation before sending the result to an api), and they're pointing out that if the initial synchronous part of the task takes a long time or throws an exception then so will the caller, so it's not really a "safe" fire & forget –  Harry Commented Aug 1, 2023 at 14:27

I guess the question arises, why would you need to do this? The reason for async in C# 5.0 is so you can await a result. This method is not actually asynchronous, but simply called at a time so as not to interfere too much with the current thread.

Perhaps it may be better to start a thread and leave it to finish on its own.

Drew Noakes's user avatar

  • 2 async is a bit more than just "awaiting" a result. "await" implies that the lines following "await" are executed asynchronously on the same thread that invoked "await". This can be done without "await", of course, but you end up having a bunch of delegates and lose the sequential look-and-feel of the code (as well as the ability to use using and try/catch ... –  Peter Ritchie Commented Mar 20, 2013 at 13:09
  • 3 @PeterRitchie You can have a method that is functionally asynchronous, doesn't use the await keyword, and doesn't use the async keyword, but there is no point whatsoever in using the async keyword without also using await in the definition of that method. –  Servy Commented Mar 20, 2013 at 15:56
  • 2 @PeterRitchie From the statement: " async is a bit more than just "awaiting" a result." The async keyword (you implied it's the keyword by enclosing it in backticks) means nothing more than awaiting the result. It's asynchrony, as the general CS concepts, that means more than just awaiting a result. –  Servy Commented Mar 20, 2013 at 16:35
  • 1 @Servy async creates a state machine that manages any awaits within the async method. If there are no await s within the method it still creates that state machine--but the method is not asynchronous. And if the async method returns void , there's nothing to await. So, it's more than just awaiting a result. –  Peter Ritchie Commented Mar 20, 2013 at 19:43
  • 1 @PeterRitchie As long as the method returns a task you can await it. There is no need for the state machine, or the async keyword. All you'd need to do (and all that really happens in the end with a state machine in that special case) is that the method is run synchronously and then wrapped in a completed task. I suppose technically you don't just remove the state machine; you remove the state machine and then call Task.FromResult . I assumed you (and also the compiler writers) could add the addendum on your own. –  Servy Commented Mar 20, 2013 at 23:25

On technologies with message loops (not sure if ASP is one of them), you can block the loop and process messages until the task is over, and use ContinueWith to unblock the code:

This approach is similar to blocking on ShowDialog and still keeping the UI responsive.

haimb's user avatar

Typically async method returns Task class. If you use Wait() method or Result property and code throws exception - exception type gets wrapped up into AggregateException - then you need to query Exception.InnerException to locate correct exception.

But it's also possible to use .GetAwaiter().GetResult() instead - it will also wait async task, but will not wrap exception.

So here is short example:

You might want also to be able to return some parameter from async function - that can be achieved by providing extra Action<return type> into async function, for example like this:

Please note that async methods typically have ASync suffix naming, just to be able to avoid collision between sync functions with same name. (E.g. FileStream.ReadAsync ) - I have updated function names to follow this recommendation.

TarmoPikaro's user avatar

Maybe I'm too naive but, couldn't you create an event that is raised when GetStringData() is called and attach an EventHandler that calls and awaits the async method?

Something like:

And somewhere in the code attach and detach from the event:

Not sure if this might be anti-pattern somehow (if it is please let me know), but it catches the Exceptions and returns quickly from GetStringData().

Miguel's user avatar

  • 2 This is just an overly convoluted way of converting an asynchronous method to async void , so that the behavior is changed from fire-and-forget to fire-and-crash. You can achieve the same thing in a straightforward manner like this: async void OnErrorCrash(this Task task) => await task; –  Theodor Zoulias Commented Nov 19, 2020 at 17:01

The solution is start the HttpClient into another execution task without sincronization context:

Ernesto Garcia's user avatar

It is straightforward, just call asyncMethod().Result to call without await. Below is the sample code and here is the fiddle

DanielV's user avatar

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged c# exception async-await task task-parallel-library or ask your own question .

  • Featured on Meta
  • Upcoming initiatives on Stack Overflow and across the Stack Exchange network...
  • Announcing a change to the data-dump process
  • What makes a homepage useful for logged-in users

Hot Network Questions

  • Can a non-symmetrical distribution have the same areas under the PDF in the two sides around the mean?
  • In the onion-like elemental layers of a large mature star the neon is closer to the surface than oxygen, even though it is more massive... Why?
  • How do Trinitarian Christians respond to these differences between Jesus Christ and God
  • How to ask Mathematica to find the nontrivial (nonzero) solution of a homogeneous system of equations?
  • Within Microsoft Word, how do you continue a page number from a different document - not a different section within the same document
  • Will this 3.3 V signal voltage be high enough to close Q3?
  • What happens if a leading Presidential candidate dies with no running mate?
  • Zugzwang where the side to move must be mated in exactly 2 moves
  • How to choose a textbook that is Pedagogically Optimal for oneself?
  • Clock that is twice as fast
  • Is evolution anti-entropic?
  • What am I doing wrong if people repeat their original offers and requests despite me declining them?
  • Can natural decreasing temperatures in the world create energy to power it?
  • Is observing any day by a Reformed Christian tantamount to keeping ceremonial law?
  • "commit" a crime
  • 80s live-action short film with a labyrinth/elf/handprint/minotaur
  • Are unique filtered indexes considered an antipattern for enforcing constraints?
  • How do you import the name ‘Aer’ from qiskit? (Jupyter Notebook)
  • Is there a more concise method to solve the problem of finding tangent lines to curves?
  • Does a power supply wear out?
  • Winload.exe booting process
  • Is a continuous function a generalization of an adjunction?
  • Why call for Biden to step down now?
  • Was the head of the Secret Service ever removed for a security failure?

task async net core

task async net core

Get notified in your email when a new post is published to this blog

Creating an already-completed asynchonous activity in C++/WinRT, part 1

' data-src=

Raymond Chen

July 9th, 2024 2 1

When working with asynchronous code, you may need to create an asynchronous activity that has already completed, because you already know the answer. For example, you may be implementing a method whose signature is

but you already have the result and don’t need to compute it. How can you return an IAsyncOperation<int> that represents the already-computed result?

C# has Task.FromResult() and Task.CompletedTask . JavaScript has Promise.resolve() . The Parallel Patterns Library (PPL) has task_ from_ result() . What about C++/WinRT?

The simplest way is to just co_return the result into a coroutine.

Similarly, C# has Task.FromException() , JavaScript has Promise.reject() , and PPL has task_ from_ exception() . The simple C++/WinRT version is to throw the exception from the coroutine.

But wait, this doesn’t do what you think:

There is no co_await or co_return statement in the function body, so this is not a coroutine: Instead of returning a failed coroutine, this function fails to return a coroutine! When you call it, it throws an exception.

We’ll look at ways of making this a coroutine next time.

' data-src=

Leave a comment Cancel reply

Log in to join the discussion or edit/delete existing comments.

Perhaps the following?

I’m not sure how IAsyncOperation’s promise type handles the situation where dynamic allocation of the coroutine frame fails, that usually results in throwing std::bad_alloc, so you can’t mark the function as noexcept in that case. If it has some non-throwing way of handling that case though then I suppose the noexcept is fine. It’s a shame there’s no way for a promise type to detect whether the function signature contains noexcept or not.


Insert/edit link

Enter the destination URL

Or link to existing content


  1. Async processing of long-running tasks in ASP.NET Core

    task async net core

  2. Asynchronous Programming with Async and Await in ASP.NET Core

    task async net core

  3. Async processing of long-running tasks in ASP.NET Core

    task async net core

  4. Async processing of long-running tasks in ASP.NET Core

    task async net core

  5. How to run async tasks in ASP.NET Core? » Coding Life

    task async net core

  6. Asynchronous Programming with Async and Await in ASP.NET Core

    task async net core


  1. [.Net 소스코드 열어보기] CancellationToken의 구현을 알아보자

  2. How to use an asynchronous operation inside Background Task

  3. 【プログラミング講座(C#)】第143回 Task、async、await について【独り言】

  4. Parte 7: ConfigureAwait

  5. 1- ) Parallel Programming- .Net Parallel Programming

  6. 4- ) Async Await & Parallel Foreach, Concurrent- .Net Parallel Programming


  1. The Task Asynchronous Programming (TAP) model with async and await

    An async method typically returns a Task or a Task<TResult>. Inside an async method, an await operator is applied to a task that's returned from a call to another async method. You specify Task<TResult> as the return type if the method contains a return statement that specifies an operand of type TResult.

  2. Using async/await or task in web api controller (.net core)

    Use TaskWhenAll to return awaitable Task object. Thus with async method you can await for tasks instead of blocking thread. Instead of creating local variables and assigning them in tasks, you can use Task<T> to return results of required type. Instead of creating and running tasks, use Task<TResult>.Run method.

  3. Task-based asynchronous programming

    Show 15 more. The Task Parallel Library (TPL) is based on the concept of a task, which represents an asynchronous operation. In some ways, a task resembles a thread or ThreadPool work item but at a higher level of abstraction. The term task parallelism refers to one or more independent tasks running concurrently.

  4. Consuming the Task-based Asynchronous Pattern

    When you use the Task-based Asynchronous Pattern (TAP) to work with asynchronous operations, you can use callbacks to achieve waiting without blocking. For tasks, this is achieved through methods such as Task.ContinueWith. Language-based asynchronous support hides callbacks by allowing asynchronous operations to be awaited within normal control ...

  5. Asynchronous Programming with Async and Await in ASP.NET Core

    These two keywords - async and await - play a key role in asynchronous programming in ASP.NET Core. We use the async keyword in the method declaration and its purpose is to enable the await keyword within that method. So yes, you can't use the await keyword without previously adding the async keyword in the method declaration.

  6. Built in options for running async tasks

    This is the first post in the series: Running async tasks on app startup in ASP.NET Core. Part 1 - Built in options for running async tasks (this post) Part 2 - Two approaches for running async tasks. Part 3 - Feedback on async task examples and another possible solution. Part 4 - Using health checks to run async tasks in ASP.NET Core.

  7. Task-based Asynchronous Pattern (TAP): Introduction and overview

    In this article. In .NET, The task-based asynchronous pattern is the recommended asynchronous design pattern for new development. It is based on the Task and Task<TResult> types in the System.Threading.Tasks namespace, which are used to represent asynchronous operations.

  8. Asynchronous programming with async, await, Task in C#

    The LongProcess() method is also marked with the async keyword which makes it asynchronous. The await Task.Delay(4000); holds the thread execute for 4 seconds. Now, the program starts executing from the async Main() method in the main application thread. The async LongProcess() method gets executed in a separate thread and the main application ...

  9. How Async/Await Really Works in C#

    It's also evolved further from the initial rewrite for .NET Core, with additional optimizations that benefit from having internal access to key components in the system. In particular, the async infrastructure knows about core types like Task and TaskAwaiter. And because it knows about them and has internals access, it doesn't have to play ...

  10. How to use async and await in .NET Core

    The following code snippet illustrates how the async and await keywords are used. public async Task GetDataAsync() {. using (SqlConnection connection = new. SqlConnection(connectionString ...

  11. Creating an Async Web API with ASP.NET Core

    How to use async & await in ASP.NET Core. Let's understand the usage of async & await in async Web API with ASP.NET Core. In ASP.NET Core C# we make use of async and await keywords to implement asynchronous programming. For a method to be asynchronous we have to add the async keyword in the method definition before the return type of the method.

  12. Two approaches for running async tasks

    This is the second post in the series: Running async tasks on app startup in ASP.NET Core. Part 1 - Built in options for running async tasks. Part 2 - Two approaches for running async tasks (this post) Part 3 - Feedback on async task examples and another possible solution. Part 4 - Using health checks to run async tasks in ASP.NET Core.

  13. Parallel.ForEachAsync() and Task.Run() With When.All in C#

    Here, we use the Task.Run() method to execute AsyncMethod() three times in a row. Again, by skipping the await keyword we are not awaiting any method to complete, but we run them in parallel and on Task.WhenAll() await their results. Now, let's retake a look at the output logs when executing the request:

  14. Understanding Multitasking and Multithreading in ASP.NET and .NET Core

    Learn about multitasking and multithreading in ASP.NET and .NET Core. Discover how async/await keywords enhance responsiveness, manage concurrent operations efficiently, and handle IO-bound tasks. Explore real-world examples and differences between these techniques for optimized application performance.

  15. c#

    If your async method needs to return int you'd mark the return type of the method as Task<int> and you'll return plain int not the Task<int>. Compiler will convert the int to Task<int> for you. private async Task<int> MethodName() {. await SomethingAsync(); return 42;//Note we return int not Task<int> and that compiles.

  16. Async and Await in C# with Examples

    In this way, we are avoiding blocking the current thread that we're using and then that thread can be used in another task. Async and await works in any .NET development environment like Console applications, Windows Form applications, ASP.NET Core for Web development, Blazor for interactive web applications, etc.

  17. Avoid Awaiting Foreign Tasks in ASP.NET Core: Analyzer Warning Explanation

    Avoiding awaiting foreign tasks is an essential best practice when developing applications using ASP.NET Core. By following the best practices outlined in this article, you can help ensure that your application is performant, scalable, and free from synchronization issues. References. Consuming the Task-based Asynchronous Pattern; Asynchronous ...

  18. ASP.NET Core Basics: 12 Questions and Answers for Beginners

    ASP.NET Core is a modern, high-performance, cross-platform web development framework for .NET. It is an evolution of the ASP.NET platform, designed to be more modular and lightweight, and able to work on multiple platforms. ASP.NET Core allows developers to build web applications and services using the C# programming language.

  19. Generate Images Using OpenAI in an ASP.NET Core Application

    Create and Configure an ASP.NET Core Application. Now let's configure an ASP.NET Core Web API application with Azure OpenAI support. First, let's create an ASP.NET Core Web API application, using either the Visual Studio templates or the dotnet new webapi command. After that, let's add the Azure.AI.OpenAI NuGet package:

  20. How to use cancellation tokens in ASP.NET Core 7

    An async task receives a cancellation token and examines it to see if a cancellation is requested. If so, the current operation should cease immediately. Long running requests in ASP.NET Core

  21. Asynchronous programming scenarios

    The core of async programming is the Task and Task<T> objects, which model asynchronous operations. They are supported by the async and await keywords. The model is fairly simple in most cases: For I/O-bound code, you await an operation that returns a Task or Task<T> inside of an async method. For CPU-bound code, you await an operation that is ...

  22. Synchronous vs Asynchronous: Task.WaitAll and Task.WhenAll in .NET

    Synchronous vs Asynchronous: Explore the distinctions between Task.WaitAll and Task.WhenAll in .NET programming. Learn how Task.WaitAll synchronously waits for all tasks to complete, while Task.WhenAll asynchronously waits, enabling concurrent task execution.

  23. ASP.NET Core API

    ActionResult<T> is a new type added to allow an app to return either a response type or any other action result (similar to IActionResult ), while still indicating the response type. ActionResult<T> is more specific to Web APIs in ASP.NET Core >= 2.1 and ActionResult<T> offers the following benefits over the IActionResult type: The ...

  24. Share Identity Bearer Tokens among ASP.NET Core Web APIs

    Source Codes at GitHub; Tag V2 for this article; Introduction. This article serves as a follow-up to "Decouple ASP.NET Core Identity, Authentication and Database Engines".In this sequel, we delve into software engineering practices that promote decoupling, making them conducive to Test-Driven Development (TDD) and rapid development of enterprise applications, in contrast to god assembly ...

  25. c#

    1. Do not use Task.Run to make a synchronous API asynchronous. Using Task.Run in ASP.Net (FX and Core) is an anti-pattern. The expectation when you see/use Task.Run is that you are offloading work that will be completed in the background. Often in ASP.Net you might think you want to do this so that a HttpRequest can be completed and a response ...

  26. JWT Authentication And Authorization In .NET 6.0 With Identity Framework

    Create ASP.NET Core Web API using Visual Studio 2022 . We need Visual Studio 2022 to create .NET 6.0 applications. We can choose the ASP.NET Core Web API template from Visual Studio 2022. We can give a suitable name for our project and choose the .NET 6.0 framework. Our new project will be created in a few moments.

  27. Using Asynchronous Methods in ASP.NET MVC 4

    The async keyword represents a hint that you can use to mark methods as task-based asynchronous methods. The combination of await, async, and the Task object makes it much easier for you to write asynchronous code in .NET 4.5. The new model for asynchronous methods is called the Task-based Asynchronous Pattern (TAP).

  28. How to safely call an async method in C# without await

    However, just to address "Call an async method in C# without await", you can execute the async method inside a Task.Run. This approach will wait until MyAsyncMethod finish. public string GetStringData () { Task.Run ( ()=> MyAsyncMethod ()).Result; return "hello world"; }

  29. Creating an already-completed asynchonous activity in C++/WinRT, part 1

    When working with asynchronous code, you may need to create an asynchronous activity that has already completed, because you already know the answer. For example, you may be implementing a method whose signature is. IAsyncOperation<int> ComputeAsync(); but you already have the result and don't need to compute it.