Skip to main content

Posts

Showing posts from November, 2022

Url.ActionLink() is not thread-safe

I have an API that allows users to upload documents. To optimize the performance I save the documents to the database in parallel. After uploading has completed I return a list of URI's pointing to the document locations. Here is what the code looks like: As you can see in the code above, I combine a Task.WhenAll with a local function . Nothing special. However when I executed this code under high load, I started to get errors back from the API. A look at the logs, showed the following exception: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: chunkLength at System.Text.StringBuilder.ToString()   at Microsoft.AspNetCore.Mvc.Routing.UrlHelperBase.GenerateUrl(String protocol, String host, String path)   at Microsoft.AspNetCore.Mvc.Routing.EndpointRoutingUrlHelper.Action(UrlActionContext urlActionContext)   at Microsoft.AspNetCore.Mvc.UrlHelperExtensions.ActionLink(IUrlHelper helper, String action, Stri...

TDD, where did it all go wrong?

Every year, a new generation of developers start their career. And every year, I see these new developers struggling with writing tests. And if you dare to go one step further, and introduce them to Test Driven Development, they get even more confused. Don't misunderstand me, they are quite fast in understanding the mechanics of the testing frameworks(MsTest, Xunit, ...). But it turns out that is really hard to write good, maintainable tests that help to move forward instead of becoming a bottleneck. One of the reasons this is such a problem, is that what is now described as Test Driven Development is not aligned with the original intention. Ian Cooper has a great talk exactly about this issue: Ian Cooper reminds what was Kent's original proposition on TDD, what misunderstandings occurred along the way and suggests a better approach to TDD, one that supports development rather impeding it. There are 2 key elements of his talk, that I think are most important: ...

Using Event Counters with Application Insights

When adding the Application Insights SDK to your application, a set of Performance Counters is tracked by default. This is the list of default counters for ASP.NET web applications: % Process\Processor Time % Process\Processor Time Normalized Memory\Available Bytes ASP.NET Requests/Sec .NET CLR Exceptions Thrown / sec ASP.NET ApplicationsRequest Execution Time Process\Private Bytes Process\IO Data Bytes/sec ASP.NET Applications\Requests In Application Queue Processor(_Total)\% Processor Time However Performance Counters are a windows only feature. With .NET being cross-platform, is there a solution that works on both Windows and Linux? Of course there is! (Otherwise I wouldn’t be writing this blog post). Collecting EventCounters with Application Insights The documentation has the following to say about EventCounters: EventCounter is .NET/.NET Core mechanism to publish and consume counters or statistics. EventCounters are suppor...

EF Core 7 - Handling deletes

I’m still catching up on all the improvements that come with the release of .NET 7. One thing I noticed is a nice new feature in EF Core 7 . Before EF Core 7 when you want to delete an entity you had to fetch it first. With the new ExecuteDelete (and ExecuteUpdate ) method you can execute delete commands (and update commands) directly in the database. Executing the code above will result in the following query: As you can see, it generates a SQL statement to delete the entities that match the condition. Exactly what you would expect and without the overhead of loading the entities in memory first. Nice! Remark: EF Core 7 can be used with .NET 6. So you can start using this feature without having to upgrade to .NET 7 first. Also keep the following in mind when using the ExecuteDelete method: The specific changes to make must be specified explicitly; they are not automatically detected by EF Core. Any tracked entities will not be kept in sync. Additional comma...

Monitor your application using Event Counters - Part III

I'm building a data pipeline using TPL Dataflow to migrate data from a database to an external API. As this data pipeline could run for a long time, I was looking for a good way to monitor the progress. This turned out to be a perfect use case for Event Counters . So far we have seen how to create a simple EventCounter using a PollingCounter and how to read out its value using the dotnet-counters global tool. The PollingCounter uses a callback to determine the value that is reported. With each time interval, the user provided callback function is invoked and the return value is used as the counter value. This allows us to manage and track the number of migrated documents ourselves. Let’s continue today and have a look at how we can use some of the other counters to improve our metrics. Tracking the migration rate using the IncrementingPollingCounter We are already tracking the number of migrated documents. Wouldn’t it be nice to also track the number of documents that...

Monitor your application using Event Counters–Part II

I’m building a data pipeline using TPL Dataflow to migrate data from a database to an external API. As this data pipeline could run for a long time, I was looking for a good way to monitor the progress. This turned out to be a perfect use case for Event Counters . Yesterday I introduced EventCounters and showed a small example. Today let’s have a look on how we can monitor the EventCounters values. Monitor EventCounters using dotnet-counters There are multiple ways to read out EventCounters values but the way I want to use during the migration is through the dotnet-counters global tool : dotnet-counters is a performance monitoring tool for ad-hoc health monitoring and first-level performance investigation. It can observe performance counter values that are published via the EventCounter API or the Meter API. For example, you can quickly monitor things like the CPU usage or the rate of exceptions being thrown in your .NET Core application to see if there's anything suspic...

Monitor your application using Event Counters–Part I

I’m building a data pipeline using TPL Dataflow to migrate data from a database to an external API. As this data pipeline could run for a long time, I was looking for a good way to monitor the progress. This turned out to be a perfect use case for Event Counters . What are EventCounters? Here is what the documentation has to say about Event Counters: EventCounters are .NET APIs used for lightweight, cross-platform, and near real-time performance metric collection. EventCounters were added as a cross-platform alternative to the "performance counters" of .NET Framework on Windows. EventCounters can be used to track various metrics. And somewhat further in the documentation: Apart from the EventCounters that are provided by the .NET runtime, you may choose to implement your own EventCounters. And that is exactly what we are going to do! Implement our first EventCounter There are 4 types of counters that you can use each with their own characteristics and use...

Cloudbrew 2022–Advanced telemetry with Azure Monitor Application Insights

This weekend I had the honor to speak at CloudBrew , a 2 day conference organized by AZUG, the Belgium Microsoft Azure User Group. I really enjoyed the conference; great sessions, nice location, good food. I had the time to chat up with some other community members. Advanced telemetry with Azure Monitor Application Insights I did a session about Application Insights: You've added the Application Insights NuGet or NPM package to your application, but now what? This demo-driven session will show you how to get the maximum out of Application Insights and achieve true insights in your application behavior and performance. Profiling, dependency tracking, snapshots, extensibility, availability,... no feature remains untouched. In case you are looking for my slides, they can be found here: https://github.com/wullemsb/presentations/tree/main/CloudBrew%20-%202022 During my presentation I used 2 demo applications. They are both an adaption of the eShopOnWeb reference appli...

.NET 6–How to use arguments in your Console app?

In .NET 6 (and newer) when you create a new Console application , the result is really minimal: That is a big difference if you compare this with what you had before: This is possible thanks to some new C# features like Top Level Statements and Implicit Using Directives . But what if you want to use arguments inside your Console app? Before the arguments where available through the ‘args’ parameter that was available as an argument of the ‘Main’ method. But now there is no method, so what should you do? Turns out that you can just use the args parameter although it isn’t defined anywhere: Behind the scenes the compiler will generate a Main method for your and provide the args parameter. From the documentation : The entry point method always has one formal parameter, string[] args . The execution environment creates and passes a string[] argument containing the command-line arguments that were specified when the application was started. The string[] argument i...

SQL Server - Change the column size without needing a DROP / RECREATE

While monitoring a production system, I noticed a lot of "String or binary data would be truncated" exceptions. This is an indication that the string data that would be persisted is larger than the database column allows. That’s an easy one to fix! So I opened up SQL Server Management Studio , right click on the table that was causing the problem and choose Design from the context menu. I altered the column size and hit Save . However this resulted in the following message: SQL Server Management Studio tries to handle the resize operation by executing a ‘DROP’ and re‘CREATE’ of the table. As this would result in a loss of all the data, the operation is prevented. But I’m making an existing column larger. I would except that this is a safe operation that can be executed without any risk of data loss? Instead of using the designer I switched to a small SQL snippet: Remark: Don’t forget to include the ‘NOT NULL’  modifier otherwise you end up with a NULL...

Azure Application Insights – Set cloud role name in your Javascript frontend

One of the nice features of Application Insights, is the Application Map. This gives you a visual clue of all the parts of your application and their dependencies. I blogged before on how you could tweak this application map through a custom TelemetryInitializer: In your C# backend In your Angular SPA Today I want to share another option when you are using the Javascript snippet inside your web frontend. Inside the snippet you should use the onInit callback to inject a TelemetryInitializer: Here is the full snippet as well:

Blazor - Failed to find a valid digest in the 'integrity' attribute

After making a small change to a Blazor application, I redeployed it to an Azure App service. When I tried to open the updated Blazor application nothing happened. When I opened up the browser console, I noticed a list of errors: There are 2 errors important to explain what is going wrong: Failed to find a valid digest in the 'integrity' attribute for resource 'https://cloudbreweshopweb.azurewebsites.net/_framework/dotnet.timezones.blat' with computed SHA-256 integrity '2NJf++ql6UnbRRdYWEir6MxH58bYGWDEqofII/z+Xmo='. The resource has been blocked. Failed to find a valid digest in the 'integrity' attribute for resource 'https://cloudbreweshopweb.azurewebsites.net/_framework/dotnet.wasm' with computed SHA-256 integrity 'y0gwhQ7a6FTinj6R6HEA3SlRDb/iL70a56PEGpKbt/8='. The resource has been blocked. This is related to the integrity checks executed by the browser. Integrity checks When Blazor WebAssembly downloads an app's st...

Visual Studio 2022 17.4 - Error MSB4024

Last week the latest Visual Studio 2022 update was announced; v17.4. This is not a post about all the new features but about an issue I encountered after doing the update. In the previous release Live Unit Testing was announced as a preview. At that time I enabled this preview feature to check what was possible and help me in my test driven development lifecycle. After installing the 17.4 update, this caused an unexpected side-effect. I no longer succeeded in compiling any of my projects and all of them failed with exceptions like this: Build started... 1>------ Build started: Project: BlazorShared, Configuration: Debug Any CPU ------ 1>D:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Microsoft.Common.props(73,3): error MSB4024: The imported project file "D:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Imports\Microsoft.Common.props\ImportBefore\Microsoft.LiveUnitTesting.props" could not be loaded. Root elemen...