28/02/2025

Question on C# version on VS Projects

I have recently inherited a Visual Studio 2022 project, it is a C# Console application on .Net Framework 4.8. So I thought not a very old project what can go wrong.

Well, when I worked on the project, only into first few hours, I have faced following error:

Feature 'nullable reference types' is not available in C# 7.3. Please use language version 8.0 or greater.

I got this error because I tried to use Nullable type in my new code I was developing. But I was thinking, why would this project is using C# 7.3? At the time of writing latest version of the C# was version 13, which was released with .NET 9.0 in 2024. So how come C# version used in relatively new project has taken version 7.3?

To find the answer I have turned to ChatGPT and web. This is what it had to tell:

The default version of the C# depends on the the target framework of your project. Here is the default versions for .NET Framework 4.6.2 and 4.8:

 .NET Framework Version

 Default C# Version

Maximum Supported Version

 .Net Framework 4.6.2

 C# 7.0

 C# 7.3

 .Net Framework 4.8

 C# 7.3

 Latest version as of now


That explained lot. This project was created on .Net Framework 4.8, so it has defaulted to C# version 7.3.

Next question pop-up to me was, then how can I upgrade C# version on this project to more latest version, so I can use new features in the language in my code?

Answer is, you need to manually edit the .csproj file (i.e. Visual Studio project file). You need to insert something similar to below:

<PropertyGroup>
  <LangVersion>8.0</LangVersion>
</PropertyGroup>

If you want to use latest version of the language forever, you can do following:
<PropertyGroup>
  <LangVersion>latest</LangVersion>
</PropertyGroup>

However one of the thing to consider is, although .Net Framework 4.8 support latest version of the language, some of the features require runtime support which is only available in Framework. For example async streams, interface methods require runtime support of .Net Core/.NET 5+.

Unfortunately, there is no setting to tell on Visual Studio project to tell, which version of C# language in use. So if your csproj file doesn't have above property, you need to infer that your project will use the default version of the Framework as the language version.

If you are using more modern Frameworks, here are the default C# versions go with them:
  • .NET 8 => default to C# 12
  • .NET 7 => default to C# 11
  • .NET 6 => default to C# 10

IIS Application Pool Recycling Settings

Recently I had chance to look into IIS's capability to auto recycle app pool. Because one of our web app was hogging the whole server claiming all the memory it can get when it working at its peak. 

When hosting applications on IIS (Internet Information Services), managing application pool recycling is crucial for ensuring stability and performance not only on the target app, but for whole server. Recycling helps refresh the application environment by periodically restarting the worker process to prevent memory leaks, releasing un-wanted memory, resource locking and unexpected issues. 

Recycling Settings in IIS App Pools

Recycling settings are per App Pool. There fore you can configure each pool differently. These settings can be found in Advanced Setting dialog. Right click on the desired Application Pool and go to "Advanced Settings" dialog.

There are lot of "Advanced Settings" therefore, you might have to scroll down to see these settings, they are at the right below the dialog.


"Disable overlapping recycle", "Disabling Recycling for Configuration Changes" (blog done for this), "Generate Recycle Event Log Entry" are settings which are relate to recycling but not something allow us to control recycling times. So we skip them for bit.


1. Regular Time Interval (Fixed Interval Recycling)

  • Setting Name: Regular Time Interval (in Minutes)

  • Default: 0 - means application pool will not recycle regular time intervals

  • Description: Automatically recycles the worker process after a specified time interval.

  • Use Case: Useful for applications that need periodic refreshing to prevent performance degradation. However, setting this too frequently can disrupt user sessions. For example you can set your application pool to restart every 12 hours (720 minute), when you know these 12 hour intervals are not its peak times.


2. Specific Time(s) (Scheduled Recycling)

  • Setting Name: Specific Times

  • Description: Allows recycling at predefined times during the day.


  • Use Case: Ideal for scheduled maintenance windows. For example, in above screen shot we recycle application pool at 00:05 mid night, then 3:05AM (which is probably after maintenance job), then 6.30AM (just before users try to access), 12.45PM (mid day when traffic is low when every one at lunch), 5.30PM (when users logging off), 7PM (before we kick off maintenance tasks).

3. Memory-Based Recycling

a) Private Memory Limit

  • Setting Name: Private Memory Limit (KB)

  • Description: Recycles the worker process when its private memory consumption exceeds a specified threshold.

  • Use Case: Helps prevent excessive memory usage due to memory leaks in applications. For example, if an app is expected to use a maximum of 2 GB, setting a limit slightly above (e.g., 2.5 GB) ensures it gets recycled before causing server slowdowns.

b) Virtual Memory Limit

  • Setting Name: Virtual Memory Limit (KB)

  • Description: Recycles the worker process when its virtual memory usage exceeds a specified limit.

  • Use Case: Less commonly used but can help control applications with excessive virtual memory allocations. Similar to private memory limit, but include shared memory space as well.


4. Request-Based Recycling

a) Request Limit Recycling

  • Setting Name: Request Limit

  • Description: Recycles the worker process after processing a specified number of requests.

  • Use Case: Useful for high-traffic applications where a certain number of requests may cause the application to degrade. For example, if an API handles millions of requests daily, recycling it after every 500,000 requests can help maintain performance.


There are other settings such as "Idle Time" (cause app pool to terminate or suspend when there are no requests), "CPU Limit" which can also effect the application pool recycling/terminating behavior, but we will discuss this in a separate blog.



Best Practices for Application Pool Recycling

Although above helps your recycle the claim back any un-used or over used memory, this process need to be done with care. Because Frequent recycling can disrupt user sessions and degrade performance.

Always try to recycle during off-peak hours. This will minimize disruptions to user session. 

There are settings in "Generate Recycle Event Log Entry" section which allows your to control what recycle action should be logged in Windows Event log. Use this to your advantage and track when is the actual recycling is happening by monitoring the logs for period of time. This will give more insight and use this insight to adjust the recycling settings.






Introduction to SQL Server Indexes

What are SQL Server Indexes Indexes in SQL Server servers similar purpose as they do in a book we read. In a large book, let say a book with...