한 주 동안 .NET 생태계에서 있었던 주요 이슈와 아티클, 기술 트렌드를 정리해 소개합니다.
C# 메모리 안전성 개선
- 저자: Richard Lander
- 태그: csharp #memorysafety #unsafe
주요 내용
- C# 16에서
unsafe키워드를 스코프 표시에서 호출자 의무를 명시하는 계약(contract) 시스템으로 재설계 /// <safety>문서 블록 의무화, 타입 레벨unsafe제거,extern선언에 새로운safe키워드 도입- Rust의
unsafe fn/unsafe {}모델 차용, Swift의 암시적 전파 방식과는 차별화 - 프로젝트 속성 두 개(opt-in + AllowUnsafeBlocks)로 게이트, 기본값은 unsafe 전면 차단
- .NET 11 프리뷰 도입 → .NET 12 정식,
dotnet format마이그레이션 픽서 제공 예정
.NET 11 Preview 1: Web Workers로 Blazor에서 백그라운드 작업 실행하기
- 저자: Andrew Lock
- 태그: #dotnet11 blazor #webworkers
주요 내용
- JavaScript 단일 스레드 이벤트 루프로 인한 UI 멈춤을 Web Workers의 멀티스레딩으로 해소
- .NET 11 SDK가 제공하는
webworker템플릿과[JSExport]데코레이션 기반 구현 절차 - 워커마다 자체 .NET 런타임 인스턴스 초기화 비용이 크므로 워커 참조 캐싱 필요
dotnet-web-worker-client.js(메인)와dotnet-web-worker.js(워커)의 메시지 패싱 아키텍처- 반환 타입은 원시 타입/문자열로 제한, 복합 객체는 JSON 직렬화로 전달
.NET 11의 Zstandard 압축
- 저자: Steven Giesel
- 태그: #dotnet11 #compression #zstd
주요 내용
- .NET 11에
ZstandardStream,ZstandardEncoder/Decoder,ZstandardDictionary,ZstandardCompressionOptions추가 - DEFLATE 수준 압축률에 더 빠른 압축/해제 속도, 품질 레벨 -∞ ~ 22(기본 3)
GZipStream과 유사한 API 패턴- ASP.NET Core 응답 압축에
x.Providers.Add<ZstandardCompressionProvider>()한 줄로 통합 - Dictionary 압축이 100KB 내외 유사 페이로드(JSON 등)에서 압축률 향상
.NET 11에 드디어 들어온 유니온 타입
- 저자: Andrew Lock
- 태그: #dotnet11 csharp #uniontypes
주요 내용
- C# 15(.NET 11 preview 2)의
union키워드 도입:public union SupportedOS(Windows, Linux, MacOS); - 생성자/암시적 변환으로 인스턴스 생성,
switch식의 자동 타입 추출과 컴파일러의 망라성 검사 - 구현 메커니즘:
[Union]어트리뷰트가 붙은 struct,IUnion인터페이스의object? Value - 값 타입 박싱 회피를 위한
TryGetValue()오버로드 패턴 - 사용 요건: .NET 11 SDK preview 2+,
<LangVersion>preview</LangVersion>
.NET 10 리플렉션 성능: 벤치마크, 캐싱, 델리게이트
- 저자: Nick Cosentino
- 태그: dotnet10 #reflection #performance
주요 내용
- 비싼 작업(
GetProperty/Invoke)과 빠른 작업(캐시된PropertyInfo, 컴파일된 델리게이트) 구분 - 네 가지 최적화 전략: 정적 딕셔너리 캐싱,
FrozenDictionary,Expression.Lambda().Compile(),[UnsafeAccessor] - 제네릭 멀티타입 캐시와 컴파일된 getter/setter, BenchmarkDotNet 측정 코드 포함
- 호출 빈도와 컨텍스트에 따른 단계적 적용, AOT 시나리오에서는 소스 제너레이터 우위
ReadOnlySpan<T>로 .NET Framework의 byte 할당 제거하기
- 저자: Andrew Lock
- 태그: #performance #readonlyspan #allocation
주요 내용
- C# 컴파일러가 상수 byte 배열 데이터를 어셈블리 메타데이터에 직접 임베드해 힙 할당을 제거하는 메커니즘
byte[],sbyte[],bool[]만 zero-allocation 최적화 대상이며 다른 타입은 .NET 7+ 런타임 지원 필요- 배열에 비상수 값이 섞이면 매 접근마다 전체 할당이 발생
- Collection expressions는 static 프로퍼티에서는 컴파일 타임 보호를 제공하나 로컬 변수에서는 제공하지 않음
- 런타임 변경 없이 컴파일러 기능만으로 동작해 .NET Framework 포함 모든 버전에서 사용 가능
dotnet run Hello.cs — .NET 10에서 C#이 맞이한 파이썬 같은 순간
주요 내용
- .NET 10의 파일 기반 앱 기능: 단일
.cs파일을dotnet run app.cs로 실행 - CLI가 가상 프로젝트를 자동 생성/컴파일,
#:디렉티브로 NuGet 패키지·SDK·빌드 속성을 파일 내부에 선언 - 명시적
Main없는 암묵적 진입점, async/레코드 등 모던 C# 기능 지원 dotnet project convert명령으로 스크립트를 정식 프로젝트로 승격- Console, Minimal API, CSV/JSON 처리 등 실행 예제 포함
절반만 성공한 사용 사례 — .NET에서 부분 실패 설계하기
- 저자: Milan Jovanović
- 태그: dotnet #resilience #outbox
주요 내용
- 결제/DB/이메일 다단계 작업에서의 부분 실패 문제 정의
- 부작용 3분류: 트랜잭션 내 / 외부+가역 / 외부+비가역
- 트랜잭션은 마지막에 커밋, 비가역 작업은 Outbox로 이벤트화, 외부 호출은 Idempotency Key 또는 보상 이벤트
- 멱등성 키 활용 결제 호출과
PaymentFailedEvent기반 보상 워커 예제 - Use case와 Saga의 경계 기준 제시
Uber 여행 라이프사이클로 보는 .NET 상태 머신과 EF Core
- 저자: Adrian Bailador
- 태그: #statemachine #efcore #ddd
주요 내용
- Requested → DriverAssigned → InProgress → Completed/Cancelled 상태 전이 모델링
- 허용 전이 테이블과
Validate메서드로 잘못된 전환 차단 - EF Core의 RowVersion(낙관적 동시성)으로 동시 상태 변경 방지
- Aggregate Root에서만 상태 변경 허용, 도메인 이벤트(
TripCompleted,DriverAssigned) 발행 - 안티패턴(공개 상태 필드, 분산된 검증, SaveChanges 전 이벤트 발행, ConcurrencyException 무시)과 백그라운드 타임아웃 처리
실패에서 배운 복식부기 장부 시스템 설계
- 저자: Kamogelo Ellen Kganakga
- 태그: dotnet #ledger #postgresql
주요 내용
- .NET 8 + PostgreSQL 16 기반 복식부기 장부 시스템 설계 회고
NUMERIC(19,4)로 부동소수점 오차 방지,SELECT FOR UPDATE+ UUID 정렬 잠금으로 데드락 방지- Idempotency-Key 헤더로 재시도 안전성 확보,
balance_after스냅샷으로 시계열 조회 성능 확보 - Clean Architecture 계층 분리, BCrypt + JWT(15분) + refresh token 재사용 감지
- 100달러 잔액에 10개 병렬 출금 → 정확히 5건만 성공하는 동시성 테스트로 실증
FusionCache — 캐시에 필요한 것은 TTL이 아니라 복원력 전략
- 저자: Serhat Serttaş
- 태그: #fusioncache #caching #resilience
주요 내용
- L1(메모리) + L2(Redis) + Backplane 구성과 Cache Stampede 보호 메커니즘
- Fail-Safe(데이터 소스 장애 시 만료 데이터로 폴백), Soft/Hard 타임아웃, Eager Refresh(TTL 90% 시점 백그라운드 갱신)
- Tag 기반 무효화와 Backplane을 통한 다중 노드 L1 동기화
- 50M req/day 시나리오에 대한 L1 1h / L2 24h / FailSafe 48h 권장 계층
- 약한 일관성, 메모리 중복, 복잡성 등 트레이드오프와 .NET 9 HybridCache 호환
가벼운 읽을거리
후보 항목 중 이슈로 선정되지 않은 가벼운 읽을거리들
2015년처럼 appsettings.json 읽지 말자 — .NET의 Options 패턴
IOptions<T>(싱글톤),IOptionsSnapshot<T>(요청 스코프),IOptionsMonitor<T>(반응형)의 차이와 선택 기준[Required]/[Range]/[Url]데이터 어노테이션과ValidateOnStart()를 통한 시작 시점 검증
HttpClient 실수가 프로덕션을 조용히 망가뜨린다
new HttpClient()반복 생성 시 TCP 소켓 TIME_WAIT 잔존으로 소켓 고갈, 정적 HttpClient는 DNS 캐싱으로 구식 IP 문제IHttpClientFactory의 명명/타입 기반(typed) 클라이언트 등록 패턴
List<T>가 스레드 안전하지 않다는 신호 — 오해하기 쉬운 IndexOutOfRangeException
List<T>.Enumerator.MoveNext()에서의IndexOutOfRangeException은 동시 수정의 신호, 버전 체크가 인덱스 접근 이후라 원시 예외가 먼저 노출- 해결책:
System.Collections.Concurrent타입, 모든 접근에 락, 스냅샷 후 순회
.NET에서 Dapper 마이크로 ORM을 마스터하는 완벽 가이드
QueryAsync<T>,QueryFirstOrDefaultAsync<T>,ExecuteAsync,QueryMultipleAsync등 핵심 API- 트랜잭션, 저장 프로시저, 벌크 작업, JOIN 다중 매핑까지 다루는 입문~중급 종합 가이드
.NET 현대화 Part 24: Prometheus와 Grafana를 활용한 현대적 모니터링
- OpenTelemetry + Prometheus + Grafana 메트릭/모니터링 파이프라인 구성
AddOpenTelemetry,AddAspNetCoreInstrumentation설정과 Prometheus scraping 엔드포인트, Grafana 연동 흐름
Windows Runtime에서 Win32 구조체를 사용하는 방법
- WinRT가 raw 포인터를 노출하지 않아
Win32Point { Int32 X; Int32 Y; }같은 "shadow struct"로 메모리 레이아웃을 미러링 PROPERTYKEY처럼 WinRT가 별도 표현을 쓰는 경우PSPropertyKeyFromString같은 변환 함수로 우회
