Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
159105 stories
·
33 followers

2.9.5

1 Share

Restore pipeline logic to push updates to the store by default (#41308)

Read the whole story
alvinashcraft
52 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

.NET 11 Preview 7 is now available!

1 Share

Today, we are excited to announce the seventh preview release of .NET 11! This release includes improvements across libraries, the .NET Runtime, SDK, C#, ASP.NET Core, .NET MAUI, Entity Framework Core, F#, and Windows Forms. Check out the linked release notes below and get started today.

This release contains the following improvements.

📚Libraries

⏱Runtime

🛠 SDK

C#

🌐 ASP.NET Core

📱 .NET MAUI

🎁 Entity Framework Core

F#

🖥 Windows Forms

🚀 Get started

To get started with .NET 11, install the .NET 11 SDK.

If you’re on Windows using Visual Studio, we recommend installing the latest Visual Studio 2026 Insiders. You can also use Visual Studio Code and the C# Dev Kit extension with .NET 11.

The post .NET 11 Preview 7 is now available! appeared first on .NET Blog.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

.NET and .NET Framework August 2026 servicing releases updates

1 Share

Welcome to our combined .NET servicing updates for August 2026. Let’s get into the latest release of .NET and .NET Framework. Here’s a quick overview of what’s new in our servicing releases:

Security improvements

.NET has been refreshed with the latest update as of August 11, 2026. This update contains security and non-security fixes.

This month you will find that these CVEs have been fixed:

CVE # Title Applies to
CVE-2026-62898 .NET Information Disclosure Vulnerability .NET 10.0, .NET 9.0, .NET 8.0
CVE-2026-62899 .NET Security Feature Bypass Vulnerability .NET 10.0, .NET 9.0, .NET 8.0
CVE-2026-62900 .NET Information Disclosure Vulnerability .NET 10.0, .NET 9.0, .NET 8.0
CVE-2026-62901 .NET Denial of Service Vulnerability .NET 10.0, .NET 9.0, .NET 8.0
CVE-2026-62886 .NET Elevation of Privilege Vulnerability .NET 10.0, .NET 9.0, .NET 8.0
CVE-2026-62871 .NET Elevation of Privilege Vulnerability .NET 10.0, .NET 9.0, .NET 8.0
CVE-2026-70354 .NET Core Remote Code Execution Vulnerability .NET 10.0, .NET 9.0, .NET 8.0
CVE-2026-62902 .NET Information Disclosure Vulnerability .NET 10.0, .NET 9.0, .NET 8.0
CVE-2026-62897 .NET Remote Code Execution Vulnerability .NET 10.0, .NET 9.0, .NET 8.0
CVE-2026-62909 .NET Elevation of Privilege Vulnerability .NET 10.0, .NET 9.0, .NET 8.0
.NET 10.0 .NET 9.0 .NET 8.0
Release Notes 10.0.11 9.0.19 8.0.30
Installers and binaries 10.0.11 9.0.19 8.0.30
Container Images images images images
Linux packages 10.0 9.0 8.0
Known Issues 10.0 9.0 8.0

Release changelogs

.NET Framework August 2026 Updates

This month, there are new security and non-security updates available. For recent .NET Framework servicing updates, be sure to browse our release notes for .NET Framework for more details.

See you next month

That’s it for this month, make sure you update to the latest service release today.

The post .NET and .NET Framework August 2026 servicing releases updates appeared first on .NET Blog.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

Understanding Race Conditions in ASP.NET Core

1 Share

Explore the concept of race conditions in ASP.NET Core, understand how to identify them in practice and learn strategies to protect applications against this type of issue.

Two requests arrive at your application at the exact same moment. Both read the same data, both attempt to update it, and everything appears to work correctly. Yet one update silently overwrites the other. This is a classic race condition. In this post, you’ll see how these problems arise and how to prevent them using common concurrency control techniques.

Working with systems that execute multiple operations in milliseconds is not a distant reality. On the contrary, in medium- and large-scale applications, this is a common scenario.

But along with this level of concurrency comes a problem that is often overlooked: race conditions. When not handled properly, they can lead to inconsistencies and even silently corrupt data.

In this post, we will explore the concept of race conditions, understand how to identify them in practice, and discuss strategies to protect our applications against this type of issue.

What Is a Race Condition?

According to Microsoft documentation on race conditions and deadlocks, a race condition occurs when two threads access and modify a shared resource at the same time. The final result depends on the order in which these operations are executed.

The problem is that this order is not guaranteed; it can vary with each execution. This leads to unpredictable behavior, such as inconsistent data, lost updates or invalid states.

Imagine two requests trying to update an account balance at the same time. Both read the same initial value, perform separate calculations and save the result. Depending on which one saves last, one update may overwrite the other, even if both were performed correctly in isolation.

When Do Race Conditions Occur?

Race conditions don’t appear “out of nowhere.” They usually arise from some very common code and architectural patterns. Below, we’ll look at two of the best-known: Read-Modify-Write and Check-Then-Act.

Read-Modify-Write

The idea here is simple: you read a value, make some modification to it and then write it back. The problem starts when two or more executions do this at the same time. Consider the image below:

Read modify write problem

Note that both readings happen simultaneously, returning the value of 50. However, Thread A adds 20 to the initial value, while Thread B adds 10. The problem occurs when Thread A updates the initial value (50) to 70, while Thread B updates it 1 second later with the value of 60, completely disregarding the value previously added by Thread A.

The result is an incorrectly calculated value, something that would certainly cause losses in a production environment.

Check-Then-Act

The Check-Then-Act pattern is often even more subtle than the previous pattern. The problem with this pattern is not in updating a value, but in making a decision based on a state that may change before the action takes place. Consider the image below:

Check Then Act problem

In this case we have two threads that check the stock quantity of a product. In both queries, the quantity is 1, and even though there is a check, both purchases were executed based on an invalid state. After all, when Thread A executed the purchase, there was no longer any quantity available for Thread B. If this problem had occurred in a real environment, the client of Thread B would have been left without the product.

Avoiding Race Conditions

Now that we’ve learned how to identify a race condition, let’s understand how to prevent it from happening. There are different strategies to protect ASP.NET Core applications against concurrency issues, and choosing the most appropriate approach depends on the scenario.

The main point is to understand that any concurrent operation involving shared state needs to be handled with care.

Understanding the Concept of Thread Safety

Thread safety is the ability of code or a resource to function correctly even when accessed simultaneously by multiple threads.

We can say that thread-safe code means that data is not corrupted, the state remains valid, and the behavior does not depend on the order of execution of the threads.

1. Using Locks

A lock is a mechanism used to make an operation thread-safe. It allows only one thread to execute a given piece of code at a time.

Consider the code below:

using System;
using System.Threading;
using System.Threading.Tasks;

public class ProductService
{
    private static readonly object _lock = new();

    // Simulating a stock quantity
    private int _stock = 1;

    public void Purchase(string customer)
    {
        Console.WriteLine($"{customer} is waiting to enter the critical section...");

        lock (_lock)
        {
            Console.WriteLine($"{customer} entered the critical section.");

            if (_stock <= 0)
            {
                Console.WriteLine($"{customer} could not complete the purchase. Product out of stock.");
                return;
            }

            Console.WriteLine($"{customer} is processing the purchase...");

            // Simulating a slow operation
            Thread.Sleep(3000);

            _stock--;

            Console.WriteLine($"{customer} completed the purchase.");
            Console.WriteLine($"Remaining stock: {_stock}");
        }

        Console.WriteLine($"{customer} left the critical section.");
    }
}

public class Program
{
    public static async Task Main()
    {
        var service = new ProductService();

        var task1 = Task.Run(() => service.Purchase("Customer A"));
        var task2 = Task.Run(() => service.Purchase("Customer B"));

        await Task.WhenAll(task1, task2);
    }
}

You can run this code in Fiddle and get the following result:

Lock result

The idea here is to simulate a scenario where only one unit of stock is available for two customers attempting to make a purchase simultaneously. Note that we declare a static object _lock, which acts as a guardian for the critical section of the code, so only one thread at a time can execute the logic block that checks and decrements the stock.

When the request is triggered, two distinct tasks are initiated in parallel for customers A and B. If we didn’t use the locking structure, both could read the stock value as available at the same time, resulting in a duplicate sale of an item that only exists once, which constitutes a race condition.

However, the use of the lock instruction forces a waiting queue. While the first customer processes their purchase and the system waits (Thread.Sleep), the second customer remains held at the entrance of the critical section.

Only after the first customer’s transaction is completed and the stock is updated to zero is the lock released for the next customer. Upon entering the critical section, the second client performs a logical security check, realizes that the stock has been depleted by the previous processing and ends the purchase attempt without causing data inconsistencies.

The end result is a predictable execution flow, where we guarantee data integrity in a critical scenario under concurrent demand.

2. Using SemaphoreSlim

As we saw above, a lock blocks the current thread until the critical region is released. This may not always be a good strategy, as in some cases it can reduce the scalability of the application. In these cases, SemaphoreSlim may be a more suitable alternative.

In ASP.NET Core, SemaphoreSlim is a built-in class used to limit the number of threads that can access a resource or a section of code simultaneously. When set to 1, it works similarly to a lock, allowing only one execution at a time. Consider the example below:

using System;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main()
    {
        var service = new ProductService();

        var task1 = Task.Run(() => service.PurchaseAsync("Customer A"));
        var task2 = Task.Run(() => service.PurchaseAsync("Customer B"));

        await Task.WhenAll(task1, task2);

        Console.WriteLine("Finished.");
    }
}

public class ProductService
{
    private readonly SemaphoreSlim _semaphore = new(1, 1);
    private int _stock = 1;

    public async Task PurchaseAsync(string customer)
    {
        Console.WriteLine($"{customer} is waiting to enter the critical section...");

        await _semaphore.WaitAsync();

        try
        {
            Console.WriteLine($"{customer} entered the critical section.");

            if (_stock <= 0)
            {
                Console.WriteLine($"{customer} could not complete the purchase. Product out of stock.");
                return;
            }

            Console.WriteLine($"{customer} is processing the purchase...");

            // Simulates an asynchronous operation
            await Task.Delay(3000);

            _stock--;

            Console.WriteLine($"{customer} completed the purchase.");
            Console.WriteLine($"Remaining stock: {_stock}");
        }
        finally
        {
            _semaphore.Release();

            Console.WriteLine($"{customer} left the critical section.");
        }
    }
}

You can run this code in Fiddle and get the following result:

Semaphore result

In this code, we create an instance of SemaphoreSlim, passing an initial and maximum value of 1 as a parameter. Thus, when two threads attempt to execute PurchaseAsync simultaneously, the first thread enters SemaphoreSlim while the second waits.
After the first operation is completed, the semaphore is released and the second thread can finally continue.

As in the example with lock, this prevents two operations from altering the stock at the same time. Tthe difference here is that the threads are asynchronous, and we also have the possibility of configuring an initial and maximum value for the number of simultaneous threads.

3. Using Thread-Safe Collections

Another scenario prone to race condition problems is using collections shared between multiple threads. Structures such as List<T>, Dictionary<TKey, TValue> and HashSet<T> were not designed for concurrent access. This means that collections of these types allow multiple threads to read and modify their data, generating inconsistent data and unpredictable behavior.

Consider the example below:

   private readonly Dictionary<Guid, Product> _products = new();

    public void AddProduct(Product product)
    {
        _products.Add(product.Id, product);
    }

If multiple requests attempt to add or update items at the same time, the application may throw exceptions or even corrupt the internal state of the collection. The problem occurs because Dictionary<TKey, TValue> is not prepared for synchronization.

For concurrent scenarios, .NET provides thread-safe collections through the namespace System.Collections.Concurrent, one of the most commonly used being ConcurrentDictionary<TKey, TValue>. Thus, we can use ConcurrentDictionary with safe concurrent access between multiple threads:

   private readonly ConcurrentDictionary<Guid, Product> _concurrentProducts = new();

    public void AddConcurrentProduct(Product product)
    {
        _concurrentProducts.TryAdd(product.Id, product);
    }

    public Product? GetProduct(Guid id)
    {
        _concurrentProducts.TryGetValue(id, out var product);

        return product;
    }

Now multiple threads can read _concurrentProducts at the same time, and concurrent operations are handled internally.

4. Using Optimistic Concurrency

Optimistic concurrency is another option for avoiding race conditions, especially in modern applications.

Unlike previously seen approaches such as locking or SemaphoreSlim, it does not attempt to prevent simultaneous accesses. Instead, it assumes that conflicts are rare and only detected when they occur.

Imagine that multiple operations can read the same data simultaneously. The first update happens normally, but subsequent updates fail if the data has been changed in the middle of the process. This prevents silent overwrites and provides consistency.

Consider the image below:
Optimistic Concurrency example

Note that both threads read the value at the same time (stock = 10, version 1), but Thread A was faster and updated the value first (stock = 9, version 2). When Thread B tries to update the value, an exception is generated because version 2 already exists. This verifies the consistency of the object’s initial state; in this case, the stock quantity does not receive an invalid state.

Implementing Optimistic Concurrency with EF Core

Entity Framework Core has a mechanism for using Optimistic Concurrency. To implement it, in an entity class we define a Version column as follows:

using System.ComponentModel.DataAnnotations;

namespace PracticingRaceConditions.Models;

public class Product
{
    public Guid Id { get; internal set; }
    public string Name { get; set; } = string.Empty;

    public int Stock { get; set; }

    [Timestamp]
    public byte[] Version { get; set; } = default!;
}

This Version column informs EF Core that it will be used by the Optimistic Concurrency mechanism, and when two threads attempt to update the same record with the same version, an exception will be thrown.

To simulate the error, we can do the following:

public async Task SimulatingPurchaseAsync()
{
    var options = new DbContextOptionsBuilder<ProductDbContext>()
        .UseSqlite("Data Source=productsDb")
        .Options;

    // Request A
    using var contextA = new ProductDbContext(options);

    // Request B
    using var contextB = new ProductDbContext(options);

    var productA = await contextB.Products.FirstOrDefaultAsync();

    var productB = await contextB.Products.FirstOrDefaultAsync();

    productA.Stock--;
    productB.Stock--;

    // Request A saves first
    await contextA.SaveChangesAsync();

    try
    {
        // Request B attempts to save using an outdated version
        await contextB.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        Console.WriteLine("Concurrency conflict detected!");
    }
}

If we execute the SimulatingPurchaseAsync() method, we will get the following output in the console:

Concurrency conflict error

Note that when executing the SimulatingPurchaseAsync() method, we simulate two stock changes at the same time. When saving the result of Thread A, execution occurs normally because a version 2 of the product did not yet exist. But when trying to save the result of Thread B, a DbUpdateConcurrencyException exception is thrown, because EF Core detected that a version 2 was again trying to update the record.

In this way, we can use the EF Core’s Optimistic Concurrency mechanism to prevent the race condition problem.

Conclusion

The race condition problem occurs when two threads access and modify the same resource at the same time, which can result in an invalid state depending on the order in which the operations are performed.

In this post, we’ve seen common examples where race conditions can occur, and learned how protect our code from these problems through approaches like Locks, SemaphoreSlim, Thread-Safe Collections and Optimistic Concurrency with EF Core. I hope this post has helped you understand what race conditions are and how to protect your applications from errors resulting from this type of problem.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

Today I will… manage Git Submodules without leaving the IDE

1 Share

If you’ve worked with Git submodules for any length of time, you probably have a love-hate relationship with them. They’re genuinely useful for pulling a shared library, an SDK, or common build scripts into your project. But actually working with them usually means tabbing over to a terminal and trying to remember whether it’s git submodule update --init or --init --recursive this time all while a perfectly good IDE sits right in front of you, shrugging.

That’s the part we wanted to fix. Starting in Visual Studio 18.9, Git submodules are a first-class part of the IDE no more bouncing out to the command line just to keep your dependencies in order. It’s been one of the most-requested Git features for a long time, and honestly, it’s about time.

They finally feel like part of Git in the IDE

Submodules aren’t a mystery folder anymore. There’s a dedicated Submodules section in the Git Repository window, they show up properly in Git Changes, and the branch and repository pickers actually understand how your parent repo and its submodules relate.

submodule in git repo image
    [Image: Submodules section in the Git Repository window)    

 

image image

[Image: Submodules in the Git changes window)    

Add, update, and delete without leaving your seat

From that Submodules section, you can add, update, or remove a submodule right there no memorized flags, no terminal detour. Open a solution or folder and Visual Studio discovers and activates your submodules automatically, while keeping them out of the main local repositories list so your repo picker doesn’t turn into a cluttered mess.

Selecting a submodule image

[Image: Selecting a submodule repository in Visual Studio]

Read-only by default

Most of the time you’re just *using* a submodule, not editing it, so Visual Studio treats them as read-only by default. That saves you from accidentally committing changes into a dependency you only meant to reference. When you do want to work *inside* one, it’s a single setting: Tools > Options > Source Control > Git, find Automatically activate multiple repositories, and pick Yes, include submodules.

This is just the start

This is the first milestone, not the finish line. It covers the core of what you need day to day, and there’s more coming in future releases depending on what you tell us.

We’d love to hear from you

This feature exists because so many of you kept asking for it, so keep the feedback coming. Drop your thoughts on the Feature Ticket , and if something breaks, please use the Report a Problem tool in Visual Studio is the fastest way to reach us. You can also find the team on Twitter @VisualStudio, YouTube, and LinkedIn. 

Thanks, as always, for coding with us.

The post Today I will… manage Git Submodules without leaving the IDE appeared first on Visual Studio Blog.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

Automate recurring developer tasks with the GitHub Copilot app | Tutorial for beginners

1 Share
From: GitHub
Duration: 4:13
Views: 317

Managing library updates and triaging pull requests manually every day can quickly create tech debt. In episode 4 of our beginner series, learn how to set up automations in the GitHub Copilot app to offload tedious recurring tasks. Discover how to create scheduled or issue-triggered tasks using plain English prompts, starting with a daily Dependabot review. Watch Copilot summarize open PRs and hand off complex updates so you can focus on work that needs your judgment.

Download the app today and try out automation: https://github.com/features/ai/github-app?utm_source=youtube-copilot-app-ep4-description&utm_medium=social&utm_campaign=copilot-app-for-beginners-series

#Automation #GitHubCopilot #CopilotApp

— CHAPTERS —

00:00 Offloading tedious developer chores
00:26 What is an automation in the GitHub Copilot app?
00:47 Setting up names, triggers, and schedules
01:26 Writing natural language automation prompts
02:22 Running automations and reviewing summaries
02:56 Starting a new session from automation results
03:40 Reviewing automation history and wrap-up

Stay up-to-date on all things GitHub by connecting with us:

YouTube: https://gh.io/subgithub
Blog: https://github.blog
X: https://twitter.com/github
LinkedIn: https://linkedin.com/company/github
Insider newsletter: https://resources.github.com/newsletter/
Instagram: https://www.instagram.com/github
TikTok: https://www.tiktok.com/@github

About GitHub
It’s where over 180 million developers create, share, and ship the best code possible. It’s a place for anyone, from anywhere, to build anything—it’s where the world builds software. https://github.com

Read the whole story
alvinashcraft
2 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories