hosting tips

ASP.NET Tutorial: ASP.NET Core Web API: Synchronous vs. Asynchronous Programming

Programming in Synchronous Mode
Synchronous programming involves the sequential execution of tasks one after the other. A synchronous API requires that the server process requests and wait for them to be finished before proceeding to the next job. This implies that if an action takes a long time to complete, it may prevent other operations from starting, which could cause clients to receive responses more slowly.

Programming in an Asynchronous Environment
Asynchronous programming, on the other hand, enables the simultaneous execution of tasks. An asynchronous API allows the server to execute requests without waiting for the completion of prior activities, allowing it to start tasks as a request comes in. Better scalability and responsiveness may result from this, particularly in situations where specific operations—like I/O operations—may take some time.

Web API for ASP.NET Core

You can choose between synchronous and asynchronous programming models in ASP.NET Core Web API. Both strategies are supported by the framework. When handling I/O-bound operations, such accessing a database or making external API calls, asynchronous programming comes in very handy since it allows the application to carry out other tasks while it waits for the I/O activity to finish.

You can write non-blocking code in your controller methods by using the `async` and `await` keywords to implement asynchronous programming in ASP.NET Core Web API. This enhances your API’s overall responsiveness and performance, particularly in high concurrency settings.

Asynchronous programming with ASP.NET Core Web API can improve scalability and responsiveness by enabling the server to manage several tasks at once, even while synchronous programming is simple. The particular needs and features of your application will determine whether to use synchronous or asynchronous programming.

Now let’s begin the full implementation.

Create Model

namespace SyncVsAsyncProgrammingIn.NETCoreAPI.Model
{
    public class User
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Address { get; set; }
        public string Country { get; set; }
        public string ZipCode { get; set; }

    }
}

Application Db Context

using Microsoft.EntityFrameworkCore;
using SyncVsAsyncProgrammingIn.NETCoreAPI.Model;
using System.Collections.Generic;

namespace SyncVsAsyncProgrammingIn.NETCoreAPI.ApplicationDbContext
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options)
            : base(options)
        {

        }
        public DbSet<User> Users { get; set; }

    }
}

IUserRepository Interface For User Repository

using SyncVsAsyncProgrammingIn.NETCoreAPI.Model;

namespace SyncVsAsyncProgrammingIn.NETCoreAPI.IRepository
{
    public interface IUserRepository
    {
        Task<User> GetUserByIdAsync(int id);
        User GetUserByIdSync(int id);
    }
}

User Repository

using Microsoft.EntityFrameworkCore;
using SyncVsAsyncProgrammingIn.NETCoreAPI.ApplicationDbContext;
using SyncVsAsyncProgrammingIn.NETCoreAPI.IRepository;
using SyncVsAsyncProgrammingIn.NETCoreAPI.Model;

namespace SyncVsAsyncProgrammingIn.NETCoreAPI.Repository
{
    public class UserRepository : IUserRepository
    {
        private readonly AppDbContext _dbContext;
        private readonly ILogger<UserRepository> _logger;

        public UserRepository(AppDbContext dbContext, ILogger<UserRepository> logger)
        {
            _dbContext = dbContext;
            _logger = logger;
        }

        public User GetUserByIdSync(int id)
        {
            try
            {
                // Synchronous database query
                return _dbContext.Users.FirstOrDefault(u => u.Id == id);
            }
            catch(Exception ex)
            {
                _logger.LogError($"Error in UserRepository.GetUserById: {ex.Message}");
                throw new ApplicationException("An error occurred while fetching user details. Please try again later.");
            }
        }

        public async Task<User> GetUserByIdAsync(int id)
        {
            // Asynchronous database query
            try
            {
                return await _dbContext.Users.FirstOrDefaultAsync(u => u.Id == id);
            }
            catch(Exception ex)
            {

                _logger.LogError($"Error in UserRepository.GetUserById: {ex.Message}");
                throw new ApplicationException("An error occurred while fetching user details. Please try again later.");
            }
        }
    }
}

Register the Service in the Program.cs Class

using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;
using SyncVsAsyncProgrammingIn.NETCoreAPI.ApplicationDbContext;
using SyncVsAsyncProgrammingIn.NETCoreAPI.IRepository;
using SyncVsAsyncProgrammingIn.NETCoreAPI.Repository;

var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
var configuration = builder.Configuration;

// Add services to the container.
builder.Services.AddDbContext<AppDbContext>(options =>
{
    options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")); // Replace with your database provider and connection string
});
// Add services to the container.
builder.Services.AddTransient<IUserRepository , UserRepository>();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Sync Vs Async Programming In Asp.Net Core Web API", Version = "v1" });

});
var app = builder.Build();

// Configure the HTTP request pipeline.
if(app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

ASyncUserController

using Microsoft.AspNetCore.Mvc;
using SyncVsAsyncProgrammingIn.NETCoreAPI.IRepository;

namespace SyncVsAsyncProgrammingIn.NETCoreAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ASyncUserController : ControllerBase
    {
        private readonly IUserRepository _userRepository;
        public ASyncUserController(IUserRepository userRepository)
        {
            _userRepository = userRepository;
        }

        [HttpGet(nameof(GetUserByIdAsync))]
        public async Task<IActionResult> GetUserByIdAsync(int id)
        {
            try
            {
                // Asynchronous database call
                var user = await _userRepository.GetUserByIdAsync(id);

                if(user == null)
                {
                    return NotFound(); // 404 Not Found
                }

                return Ok(user); // 200 OK with user details
            }
            catch(Exception ex)
            {
                // Handle exceptions
                return StatusCode(500, $"Internal Server Error: {ex.Message}");
            }
        }
    }
}

SyncUserController

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SyncVsAsyncProgrammingIn.NETCoreAPI.IRepository;

namespace SyncVsAsyncProgrammingIn.NETCoreAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class SyncUserController : ControllerBase
    {
        private readonly IUserRepository _userRepository;

        public SyncUserController(IUserRepository userRepository)
        {
            _userRepository = userRepository;
        }

        [HttpGet(nameof(GetUserById))]
        public IActionResult GetUserById(int id)
        {
            try
            {
                // Synchronous database call
                var user = _userRepository.GetUserByIdSync(id);

                if(user == null)
                {
                    return NotFound(); // 404 Not Found
                }

                return Ok(user); // 200 OK with user details
            }
            catch(Exception ex)
            {
                // Handle exceptions
                return StatusCode(500, $"Internal Server Error: {ex.Message}");
            }
        }
    }
}

Output

ASP.NET Core 8 Hosting Recommendation

HostForLIFE.eu
HostForLIFE.eu is a popular recommendation that offers various hosting choices. Starting from shared hosting to dedicated servers, you will find options fit for beginners and popular websites. It offers various hosting choices if you want to scale up. Also, you get flexible billing plans where you can choose to purchase a subscription even for one or six months.