From 45078c094470756bbf3b6b0c510e31940ddbefa5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Oct 2025 19:50:37 +0000 Subject: [PATCH 1/4] Initial plan From 243f0bb1734bbea501d0cd316924019d2f45a286 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Oct 2025 20:01:31 +0000 Subject: [PATCH 2/4] Add breaking change documentation for BufferedStream.WriteByte implicit flush removal Co-authored-by: gewarren <24882762+gewarren@users.noreply.github.com> --- docs/core/compatibility/10.0.md | 1 + .../10.0/bufferedstream-writebyte-flush.md | 59 +++++++++++++++++++ .../BufferedStreamWriteByteFlush.csproj | 10 ++++ .../csharp/Program.cs | 52 ++++++++++++++++ .../vb/BufferedStreamWriteByteFlush.vbproj | 9 +++ .../vb/Program.vb | 58 ++++++++++++++++++ docs/core/compatibility/toc.yml | 2 + 7 files changed, 191 insertions(+) create mode 100644 docs/core/compatibility/core-libraries/10.0/bufferedstream-writebyte-flush.md create mode 100644 docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/csharp/BufferedStreamWriteByteFlush.csproj create mode 100644 docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/csharp/Program.cs create mode 100644 docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/vb/BufferedStreamWriteByteFlush.vbproj create mode 100644 docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/vb/Program.vb diff --git a/docs/core/compatibility/10.0.md b/docs/core/compatibility/10.0.md index 7d0c66625293f..01a76074730f2 100644 --- a/docs/core/compatibility/10.0.md +++ b/docs/core/compatibility/10.0.md @@ -41,6 +41,7 @@ If you're migrating an app to .NET 10, the breaking changes listed here might af |-------|-------------------|--------------------| | [ActivitySource.CreateActivity and ActivitySource.StartActivity behavior change](core-libraries/10.0/activity-sampling.md) | Behavioral change | Preview 1 | | [Arm64 SVE nonfaulting loads require mask](core-libraries/10.0/sve-nonfaulting-loads-mask-parameter.md) | Binary/source incompatible | Preview 1 | +| [BufferedStream.WriteByte no longer performs implicit flush](core-libraries/10.0/bufferedstream-writebyte-flush.md) | Behavioral change | Preview 4 | | [C# 14 overload resolution with span parameters](core-libraries/10.0/csharp-overload-resolution.md) | Behavioral change | Preview 1 | | [Consistent shift behavior in generic math](core-libraries/10.0/generic-math.md) | Behavioral change | Preview 1 | | [Default trace context propagator updated to W3C standard](core-libraries/10.0/default-trace-context-propagator.md) | Behavioral change | Preview 4 | diff --git a/docs/core/compatibility/core-libraries/10.0/bufferedstream-writebyte-flush.md b/docs/core/compatibility/core-libraries/10.0/bufferedstream-writebyte-flush.md new file mode 100644 index 0000000000000..a318232257e04 --- /dev/null +++ b/docs/core/compatibility/core-libraries/10.0/bufferedstream-writebyte-flush.md @@ -0,0 +1,59 @@ +--- +title: "Breaking change - BufferedStream.WriteByte no longer performs implicit flush" +description: "Learn about the breaking change in .NET 10 where BufferedStream.WriteByte no longer performs an implicit flush when the internal buffer is full." +ms.date: 10/13/2025 +ai-usage: ai-assisted +ms.custom: https://github.com/dotnet/docs/issues/496356 +dev_langs: + - "csharp" + - "vb" +--- + +# BufferedStream.WriteByte no longer performs implicit flush + +Starting in .NET 10 Preview 4, the method no longer performs an implicit flush when the internal buffer is full. This change aligns the behavior of `BufferedStream.WriteByte` with other `Write` methods in the class, such as and , which do not perform an implicit flush. + +## Version introduced + +.NET 10 Preview 4 + +## Previous behavior + +When the internal buffer of a `BufferedStream` was full, calling `WriteByte` automatically flushed the buffer to the underlying stream. This behavior was inconsistent with other `Write` methods in `BufferedStream`. + +The following example demonstrates the previous behavior: + +:::code language="csharp" source="./snippets/bufferedstream-writebyte-flush/csharp/Program.cs" id="PreviousBehavior"::: +:::code language="vb" source="./snippets/bufferedstream-writebyte-flush/vb/Program.vb" id="PreviousBehavior"::: + +## New behavior + +The `WriteByte` method no longer performs an implicit flush when the internal buffer is full. The buffer is only flushed when explicitly calling the method or when the `BufferedStream` is disposed. + +## Type of breaking change + +This is a [behavioral change](../../categories.md#behavioral-change). + +## Reason for change + +The implicit flush behavior of `BufferedStream.WriteByte` was inconsistent with other `Write` methods in the `BufferedStream` class, such as `Write` and `WriteAsync`. This inconsistency could lead to unexpected performance issues or unintended side effects when working with streams that are sensitive to flush operations. Removing the implicit flush ensures consistent behavior across all `Write` methods in `BufferedStream`. + +For more details, see the [original pull request](https://github.com/dotnet/runtime/pull/104822) and the related [GitHub issue](https://github.com/dotnet/runtime/issues/104559). + +## Recommended action + +If your application relies on the implicit flush behavior of `BufferedStream.WriteByte`, update your code to explicitly call the `Flush` method when needed. For example: + +**Before:** + +:::code language="csharp" source="./snippets/bufferedstream-writebyte-flush/csharp/Program.cs" id="Before"::: +:::code language="vb" source="./snippets/bufferedstream-writebyte-flush/vb/Program.vb" id="Before"::: + +**After:** + +:::code language="csharp" source="./snippets/bufferedstream-writebyte-flush/csharp/Program.cs" id="After"::: +:::code language="vb" source="./snippets/bufferedstream-writebyte-flush/vb/Program.vb" id="After"::: + +## Affected APIs + +- diff --git a/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/csharp/BufferedStreamWriteByteFlush.csproj b/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/csharp/BufferedStreamWriteByteFlush.csproj new file mode 100644 index 0000000000000..fd4bd08da2987 --- /dev/null +++ b/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/csharp/BufferedStreamWriteByteFlush.csproj @@ -0,0 +1,10 @@ + + + + Exe + net9.0 + enable + enable + + + diff --git a/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/csharp/Program.cs b/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/csharp/Program.cs new file mode 100644 index 0000000000000..01326b671119f --- /dev/null +++ b/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/csharp/Program.cs @@ -0,0 +1,52 @@ +using System; +using System.IO; + +// +StreamWithFlush streamWithFlush = new(); +BufferedStream bufferedStream = new(streamWithFlush, bufferSize: 4); + +// Write 4 bytes to fill the buffer +bufferedStream.WriteByte(1); +bufferedStream.WriteByte(2); +bufferedStream.WriteByte(3); +bufferedStream.WriteByte(4); // In .NET 9 and earlier, this caused an implicit flush + +class StreamWithFlush : MemoryStream +{ + public override void Flush() + { + Console.WriteLine("Flush was called."); + + base.Flush(); + } +} +// + +class BeforeExample +{ + static void Example() + { + // + BufferedStream bufferedStream = new(new MemoryStream(), bufferSize: 4); + bufferedStream.WriteByte(1); + bufferedStream.WriteByte(2); + bufferedStream.WriteByte(3); + bufferedStream.WriteByte(4); // Implicit flush occurred here in .NET 9 and earlier + // + } +} + +class AfterExample +{ + static void Example() + { + // + BufferedStream bufferedStream = new(new MemoryStream(), bufferSize: 4); + bufferedStream.WriteByte(1); + bufferedStream.WriteByte(2); + bufferedStream.WriteByte(3); + bufferedStream.WriteByte(4); + bufferedStream.Flush(); // Explicit flush + // + } +} diff --git a/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/vb/BufferedStreamWriteByteFlush.vbproj b/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/vb/BufferedStreamWriteByteFlush.vbproj new file mode 100644 index 0000000000000..9b268cd35b3f9 --- /dev/null +++ b/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/vb/BufferedStreamWriteByteFlush.vbproj @@ -0,0 +1,9 @@ + + + + Exe + BufferedStreamWriteByteFlush + net9.0 + + + diff --git a/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/vb/Program.vb b/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/vb/Program.vb new file mode 100644 index 0000000000000..59041a2291f1a --- /dev/null +++ b/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/vb/Program.vb @@ -0,0 +1,58 @@ +Imports System +Imports System.IO + +Module Program + Sub Main() + ' Main entry point + End Sub +End Module + +' +Module PreviousBehaviorExample + Sub Example() + Dim streamWithFlush As New StreamWithFlush() + Dim bufferedStream As New BufferedStream(streamWithFlush, bufferSize:=4) + + ' Write 4 bytes to fill the buffer + bufferedStream.WriteByte(1) + bufferedStream.WriteByte(2) + bufferedStream.WriteByte(3) + bufferedStream.WriteByte(4) ' In .NET 9 and earlier, this caused an implicit flush + End Sub + + Class StreamWithFlush + Inherits MemoryStream + + Public Overrides Sub Flush() + Console.WriteLine("Flush was called.") + MyBase.Flush() + End Sub + End Class +End Module +' + +Module BeforeExample + Sub Example() + ' + Dim bufferedStream As New BufferedStream(New MemoryStream(), bufferSize:=4) + bufferedStream.WriteByte(1) + bufferedStream.WriteByte(2) + bufferedStream.WriteByte(3) + bufferedStream.WriteByte(4) ' Implicit flush occurred here in .NET 9 and earlier + ' + End Sub +End Module + +Module AfterExample + Sub Example() + ' + Dim bufferedStream As New BufferedStream(New MemoryStream(), bufferSize:=4) + bufferedStream.WriteByte(1) + bufferedStream.WriteByte(2) + bufferedStream.WriteByte(3) + bufferedStream.WriteByte(4) + bufferedStream.Flush() ' Explicit flush + ' + End Sub +End Module + diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index 18c08be85a233..896f5e61f9415 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -40,6 +40,8 @@ items: href: core-libraries/10.0/activity-sampling.md - name: Arm64 SVE nonfaulting loads require mask href: core-libraries/10.0/sve-nonfaulting-loads-mask-parameter.md + - name: BufferedStream.WriteByte no longer performs implicit flush + href: core-libraries/10.0/bufferedstream-writebyte-flush.md - name: C# 14 overload resolution with span parameters href: core-libraries/10.0/csharp-overload-resolution.md - name: Consistent shift behavior in generic math From 0b86a44181fefffcd39ab1d1945a97606ba14484 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Mon, 13 Oct 2025 18:03:08 -0700 Subject: [PATCH 3/4] Apply suggestions from code review --- .../10.0/bufferedstream-writebyte-flush.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/docs/core/compatibility/core-libraries/10.0/bufferedstream-writebyte-flush.md b/docs/core/compatibility/core-libraries/10.0/bufferedstream-writebyte-flush.md index a318232257e04..ed0c749a0d2b1 100644 --- a/docs/core/compatibility/core-libraries/10.0/bufferedstream-writebyte-flush.md +++ b/docs/core/compatibility/core-libraries/10.0/bufferedstream-writebyte-flush.md @@ -11,7 +11,7 @@ dev_langs: # BufferedStream.WriteByte no longer performs implicit flush -Starting in .NET 10 Preview 4, the method no longer performs an implicit flush when the internal buffer is full. This change aligns the behavior of `BufferedStream.WriteByte` with other `Write` methods in the class, such as and , which do not perform an implicit flush. +The method no longer performs an implicit flush when the internal buffer is full. This change aligns the behavior of `BufferedStream.WriteByte` with other `Write` methods in the class, such as and , which don't perform an implicit flush. ## Version introduced @@ -19,7 +19,7 @@ Starting in .NET 10 Preview 4, the method or when the `BufferedStream` is disposed. +Starting in .NET 10, the `WriteByte` method no longer performs an implicit flush when the internal buffer is full. The buffer is only flushed when the method is explicitly called or when the `BufferedStream` is disposed. ## Type of breaking change -This is a [behavioral change](../../categories.md#behavioral-change). +This change is a [behavioral change](../../categories.md#behavioral-change). ## Reason for change -The implicit flush behavior of `BufferedStream.WriteByte` was inconsistent with other `Write` methods in the `BufferedStream` class, such as `Write` and `WriteAsync`. This inconsistency could lead to unexpected performance issues or unintended side effects when working with streams that are sensitive to flush operations. Removing the implicit flush ensures consistent behavior across all `Write` methods in `BufferedStream`. - -For more details, see the [original pull request](https://github.com/dotnet/runtime/pull/104822) and the related [GitHub issue](https://github.com/dotnet/runtime/issues/104559). +The implicit flush behavior of was inconsistent with other `Write` methods in the `BufferedStream` class, such as `Write` and `WriteAsync`. This inconsistency could lead to unexpected performance issues or unintended side effects when working with streams that are sensitive to flush operations. Removing the implicit flush ensures consistent behavior across all `Write` methods in `BufferedStream`. ## Recommended action @@ -56,4 +54,4 @@ If your application relies on the implicit flush behavior of `BufferedStream.Wri ## Affected APIs -- +- From baf9731a88e0b224ce7f139093f4d8a0c0898b55 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Tue, 14 Oct 2025 11:07:21 -0400 Subject: [PATCH 4/4] Apply suggestions from code review --- .../csharp/BufferedStreamWriteByteFlush.csproj | 2 +- .../vb/BufferedStreamWriteByteFlush.vbproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/csharp/BufferedStreamWriteByteFlush.csproj b/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/csharp/BufferedStreamWriteByteFlush.csproj index fd4bd08da2987..ed9781c223ab9 100644 --- a/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/csharp/BufferedStreamWriteByteFlush.csproj +++ b/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/csharp/BufferedStreamWriteByteFlush.csproj @@ -2,7 +2,7 @@ Exe - net9.0 + net10.0 enable enable diff --git a/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/vb/BufferedStreamWriteByteFlush.vbproj b/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/vb/BufferedStreamWriteByteFlush.vbproj index 9b268cd35b3f9..e122aa2308681 100644 --- a/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/vb/BufferedStreamWriteByteFlush.vbproj +++ b/docs/core/compatibility/core-libraries/10.0/snippets/bufferedstream-writebyte-flush/vb/BufferedStreamWriteByteFlush.vbproj @@ -3,7 +3,7 @@ Exe BufferedStreamWriteByteFlush - net9.0 + net10.0