Forwarded from C# Short Posts 🔞
В пятницу классно поразгоняли с ребятами на наших внутренних техпосиделках про переезд на .NET 10.
Хедлайнером у нас был ослепительный @granstel, который перевёл свой сервис на .NET 10 первым (как минимум в Додо а может и в мире, кто знает). Сервис некритичный, но полезный — он является бэком для этой охуенной интерактивной карты. Идеальная площадка для тестов.
Так вот что удалось выяснить в процессе переезда/обсуждений:
1) В целом всё работает
2) Но есть один довольно критичный ишуй
В версии 10.0.100 внезапно сломан хендлинг вложенных try/catch/finally.
Как показано на пояснительном дикпике выше
Если внутренний finally бросает исключение, то:
внутренний catch не вызывается,
внутренний finally не доходит до конца,
внешний finally не вызывается вообще,
исключение вылетает наружу без обработки.
Довольно жёсткая штука — потому что using и await using разворачиваются компилятором именно во вложенные try/finally. А значит, при dispose может соскочить вся цепочка освобождения ресурсов.
То есть вложенный try/catch в принципе не перехватывает исключение из вложенного finally. А это уже влияет и на using, и на await using.
То есть вот такой код может быть потенциально опасным, если disposableTwo в своем диспоузе кинет исключение
using System;
using System.Threading.Tasks;
await using var disOne = new FirstDisposable("ONE");
await using var disTwo = new SecondDisposable("TWO");
Console.WriteLine("Before throw");
throw new Exception("FUCK");
sealed class FirstDisposable : IAsyncDisposable
{
private readonly string _name;
public FirstDisposable(string name) => _name = name;
public async ValueTask DisposeAsync()
{
Console.WriteLine($"DisposeAsync({_name}) START");
await Task.Delay(10);
Console.WriteLine($"DisposeAsync({_name}) END");
// На .NET 10.0.100 этот DisposeAsync вообще НЕ вызовется,
// потому что исключение из DisposeAsync(TWO) оборвёт цепочку.
Console.WriteLine($"NOTE: DisposeAsync({_name}) WAS CALLED — но это произойдёт только на .NET 8");
}
}
sealed class SecondDisposable : IAsyncDisposable
{
private readonly string _name;
public SecondDisposable(string name) => _name = name;
public ValueTask DisposeAsync()
{
Console.WriteLine($"DisposeAsync({_name}) THROWS — сейчас всё сломается");
throw new Exception($"DisposeAsync boom: {_name}");
}
}
Это утечки коннектов, файлов, сокетов, транзакций — что угодно.
Учитывая, что многие библиотеки используют IAsyncDisposable — в общем может стрельнут.
Все уже пофикшено судя по всему, наверняка заедет в следующую версию.
🚧 Вообще не всем дано переехать сразу.
Например, я попытался перевезти свою Базу знаний на новые рельсы, но столкнулся с тем, что нужный пакет Pomelo.EntityFrameworkCore.MySql пока отсутствует для .NET 10.
Так что переехать сходу смогут не все.
Может, даже и хорошо — с таким багом можно и потерпеть
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1🤯1
Кодовой Барабанщик
Дни становятся короче и душа требует #движ? Save the date: 21.11.2025 📅
Это мы перед концертом. А видос концерта наверно скоро будет
😁3❤2🔥2 1
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
This media is not supported in your browser
VIEW IN TELEGRAM
Это мы репетировали Måneskin - Beggin' месяц назад👆
❤1🔥1😁1
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3❤2
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍4❤1😁1
