[C#] 關於 .NET 10 SSE (Server-Sent Events) ,三個有感改進

2025-12-03

之前研究過 Server-Sent Events 覺得方便好用,非常符合 .NET  在開發輕巧 API 

或是單向傳遞資料,最近 .NET 10 出來了,發現他針對 SSE ( Server-Sent Events ) 有更新今天來看一下..


看一下 .NET10 修正很多,如果你想知道詳細資料可以查詢官方網站,今天整理三點我比較放在心上的

1. .NET 9 需要 FlushAsync ,似乎不用了,之前在看文件有寫到,在寫  SSE ( Server-Sent Events )  API 的時候

建議都要加上  await context.Response.Body.FlushAsync();  ,雖然我目前測試好像沒加入也沒差,但是大家都說要寫了我都會加上去

但是在 .NET10 之後似乎不需要了

.NET9 Code:

app.MapGet("/sse9-flush", async (HttpContext context, CancellationToken cancellationToken) => { context.Response.ContentType = "text/event-stream"; while (!cancellationToken.IsCancellationRequested) { await context.Response.WriteAsync($"data: v9-flush {DateTime.UtcNow}\n\n"); await context.Response.Body.FlushAsync(); //建議都要加上手動 flush await Task.Delay(1000, cancellationToken); } });


.NET10 Code:

app.MapGet("/sse10-flush", async (HttpContext context, CancellationToken cancellationToken) => { context.Response.ContentType = "text/event-stream"; while (!cancellationToken.IsCancellationRequested) { await context.Response.WriteAsync($"data: v10 {DateTime.UtcNow}\n\n"); //自動 flush await Task.Delay(1000, cancellationToken); } });


2. 取消中斷的即時性完全不同,這點很難實測,他大概意思就是 .NET 9 常常會延遲至少一次迴圈 ,.NET 10 幾乎秒停

看起來似乎沒差,但是重點是量化後,譬如成千上萬或許可能有差可以減少一次運算量,畢竟寫程式的時候我們都要假想

有好幾萬用戶同時上線 :P 


3. Minimal API 的 Header 在 .NET 10 完全自動化 ,這點差異比較大一點點,就是原本要加入一堆有的沒的 header

在 .NET 10 之後可以不用..

.NET9 Code:

app.MapGet("/sse9-minimal", async (HttpContext context, CancellationToken cancellationToken) => { //手動設定 context.Response.ContentType = "text/event-stream"; context.Response.Headers.CacheControl = "no-cache"; context.Response.Headers["X-Accel-Buffering"] = "no"; // 禁止 Nginx buffer context.Response.Headers["Content-Encoding"] = "identity"; // 禁止 gzip context.Response.Headers["Pragma"] = "no-cache"; while (!cancellationToken.IsCancellationRequested) { await context.Response.WriteAsync($"data: v9 {DateTime.UtcNow}\n\n"); await context.Response.Body.FlushAsync(); // flush await Task.Delay(1000, cancellationToken); } });


.NET10 Code:

app.MapGet("/sse10-minimal", async (HttpContext context, CancellationToken cancellationToken) => { //只需要這一行 context.Response.ContentType = "text/event-stream"; while (!cancellationToken.IsCancellationRequested) { await context.Response.WriteAsync($"data: v10 {DateTime.UtcNow}\n\n"); await Task.Delay(1000, cancellationToken); } });


這邊附上,我前端測試使用的程式碼:

<button onclick="startSSE()">Start</button> <script> let evt = null; function startSSE() { if (evt !== null) { evt.close(); //避免重複建立多條 SSE 連線 } console.log("Connecting SSE..."); evt = new EventSource("/sse9-flush"); evt.onopen = () => { console.log("SSE connected"); }; evt.onmessage = (e) => { console.log("收到資料:" + e.data); }; evt.onerror = () => { console.log("SSE 出錯,準備重連..."); evt.close(); //等 1 秒避免瘋狂重連 setTimeout(() => { startSSE(); }, 1000); }; } </script>

結論 - 

整體用下來,.NET 10 在 SSE 上的體驗真的比 .NET 9 穩定許多
.NET 9 以前那種 FlushAsync、header 手動配置、斷線延遲的問題,在 .NET 10 幾乎都不需要再額外處理

.NET 10 寫起來就是乾淨、直覺,如果你的系統有長連線或事件推播的需求

.NET 10 會比 .NET 9 更適合直接投入正式環境,維護成本也會比較低。


當麻許的碎念筆記 2014 | Donma Hsu Design.