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.

Ben.BlockingDetector

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

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

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

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.

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.

Roundup #53: .NET Core 3 Preview 9, Improved NuGet Search, Prefer ValueTask to Task, .NET Core API Performance

Here are the things that caught my eye recently in .NET.  I’d love to hear what you found most interesting this week.  Let me know in the comments or on Twitter.

Announcing .NET Core 3.0 Preview 9

Today, we’re announcing .NET Core 3.0 Preview 9. Just like with Preview 8, we’ve focused on polishing .NET Core 3.0 for a final release and aren’t adding new features. If these final builds seem less exciting than earlier previews, that’s by design.

Download .NET Core 3.0 Preview 9 right now on Windows, macOS, and Linux.

Link: https://devblogs.microsoft.com/dotnet/announcing-net-core-3-0-preview-9/

New and improved NuGet Search is here!

It’s been a long time coming, and today we are excited to announce the new and improved search on NuGet.org leveraging Azure Search. We want to start this post with a huge thanks to you, the NuGet community, for providing feedback. We have aggregated all feedback around search result relevance into one mega issue. We used this as the starting point and ensured the most egregious cases were fixed before we launched the side-by-side preview experience a few weeks ago. 70% of you voted that the new search is better! This was one of the key results in deciding to move forward leading up to today’s release.

Link: https://devblogs.microsoft.com/nuget/new-and-improved-nuget-search/

Prefer ValueTask to Task, always; and don’t await twice

A little while ago I blogged here and I set it up to be a “continues…” style post. I haven’t had the energy to continue it in that context, and this fact was putting me off concluding the post. I then realised: the thing that matters isn’t some overarching narrative structure, but that I get my ideas down. So: I’m aborting any attempt at making this post a continuation, and just focusing on the content!

Link: https://blog.marcgravell.com/2019/08/prefer-valuetask-to-task-always-and.html

Maximising .NET Core API performance

You may or may not have heard of this statistic from Google:

53% of mobile site visits leave a page that takes longer than three seconds to load
https://www.thinkwithgoogle.com/marketing-resources/data-measurement/mobile-page-speed-new-industry-benchmarks/

With that in mind, it’s important to make our site as responsive and quick as possible.

We recently rewrote one of our APIs from scratch, Saved Items, to better pave the way for new functionality and improve the performance by utilising new technologies such as .NET Core 2.

Link: https://medium.com/asos-techblog/maximising-net-core-api-performance-11ad883436c

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.

Event Sourcing: Projections with Liquid Projections

Liquid Projections

Projections are an important yet pretty simple concept when working with event-centric or event sourcing systems. The concept is to build a state from a stream of events. In my previous post, Event Sourcing with SQL Stream Store, I made a pretty basic projection to keep the current account balance. In this post, I’ll use Liquid Projections to accomplish the same task.

I recommend checking out my post on SQL Stream Store as I’m using the same example/demo application in this post.

Liquid Projections

Liquid Projection is a library for building projections. The concept and API are pretty simple, and I’ll cover the basics in this post.

First I’ll update my Demo Application to use the Liquid Projections NuGet package.

Event Map

The first building block is creating an event map. The idea is to map an event to an action that we want to be invoked when the event occurs. We can use the EventMapBuild<TContext> to create all of our event mappings. The TContext can be anything but I’ll be using it to mutate the state that represents the current balance.

As a refresher from my previous post, here is the Balance

Now using the EventMapBuilder<Balance> to handle the Deposited and Withdrawn events.

You’ll notice call Build() on the EventMapBuilder<Balance> which will return us the EventMap<Balance>. At this point, you can call Handle() to pass in the events incoming from our subscription with our current Balance.

Conditions

There are also some nice additions such as providing conditions for when to execute a map. For example, if you wanted to handle only deposited events where the amount was greater than 100.

Inheritance

There is also support for inheritance, which means since my Deposited and Withdrawn events inherit from the AccountEvent base class, I could also have done

Event Store Integration

The next on my list is write this up directly with to something like Event Store or SQL Stream Store. Stay tuned.

Check out Liquid Projections on GitHub for more.

All the source code shown in this post is available on GitHub.

If you’d like a more detailed contented related to various aspects of event sourcing, let me know in the comments or on twitter.

Related Links:

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.