DEV Community

Derek Comartin - CodeOpinion
Derek Comartin - CodeOpinion

Posted on • Originally published at codeopinion.com on

4 3

Detecting Sync over Async Code in ASP.NET Core

Sync over Async

It’s pretty easy to write some bad async code, especially when you first start using async/await. Async/await is pretty viral in .NET, which means it generally goes all the way through the stack. This can be challenging if you are trying to add async/await to an existing app and you usually end up adding sync over async code.

If you don’t use async/await correctly, and end up writing sync-over-async code, you’ll ultimately end up causing ThreadPool starvation.

Sync over Async

The term refers to making an async call but not awaiting it. Often time this is caused by calling .Wait() or .Result on the returned Task.

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace DetectAsync
{
public class BlockingDetectorController : Controller
{
[HttpGet("/sync-over-async")]
public string SyncOverAsyncMethod()
{
MyMethodAsync().Wait();
return "Hello World";
}
public async Task MyMethodAsync()
{
// Just doing a delay here to waiting 100ms like this method actually did something
await Task.Delay(100);
}
}
}

Ben.BlockingDetector

Ben Adams wrote a Blocking Detector for ASP.NET Core.

Start by adding the NuGet package Ben.BlockingDetector to your csproj.

<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Ben.BlockingDetector" Version="0.0.3" />
</ItemGroup>
</Project>
view raw csproj.xml hosted with ❤ by GitHub

At the very beginning (or the higher the better) of your Configure() method in your Startup, add the UseBlockingDetection() extension method to the IApplicationBuilder.

using Ben.Diagnostics;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
namespace DetectAsync
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseBlockingDetection();
app.UseDeveloperExceptionPage();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
view raw useBlocking.cs hosted with ❤ by GitHub

That’s it. Really. Now when we run our application and hit the /sync-over-async route from the example above, a warning is logged in the console (or however you have logging configured).

I’ve added the red arrow to point out our sync-over-async method in the call stack.

Microsoft.VisualStudio.Threading.Analyzers

Another great tool is the Microsoft.VisualStudio.Threading.Analyzers NuGet Package.

Static code analyzer to detect common mistakes or potential issues regarding threading and async coding.

Simply add it the PackageReference to your csproj and by default, you will immediately be getting warnings about sync over async calls. Here’s a screenshot in JetBrains Rider (which also can use Roslyn analyzers) that is notifying us of the issue.

Are you using any other analyzers or packages to detect blocking or problematic async code? Let me know in the comments or on Twitter.

Related Posts: I’ve also written a post on Lazy Async which try’s to solve the issue of deferring doing IO until it’s first needed.

Follow @codeopinion

The post Detecting Sync over Async Code in ASP.NET Core appeared first on CodeOpinion.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay