diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml
index 749de4d3..93ddc7da 100644
--- a/.github/workflows/benchmark.yml
+++ b/.github/workflows/benchmark.yml
@@ -13,10 +13,10 @@ jobs:
name: Run Benchmark.Net
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@v7
- uses: actions/setup-dotnet@v5
with:
- dotnet-version: 8.0.100
+ dotnet-version: 8.0.x
- name: Run benchmark
run: cd BenchmarkTests && dotnet run -c Release --framework net8.0 --exporters json --filter '*'
diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml
index d8d1cf09..d7868e5c 100644
--- a/.github/workflows/ci-cd.yml
+++ b/.github/workflows/ci-cd.yml
@@ -8,14 +8,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- uses: actions/checkout@v6
+ uses: actions/checkout@v7
# Tooling setup
- name: Install .NET SDK
uses: actions/setup-dotnet@v5
with:
- dotnet-version: 8.0.100
+ dotnet-version: 8.0.x
# Build and test validation
@@ -38,7 +38,7 @@ jobs:
--no-build
- name: Upload test results as pipeline artifact
- uses: actions/upload-artifact@v6
+ uses: actions/upload-artifact@v7
with:
name: Test results
path: 'Test results/'
@@ -65,7 +65,7 @@ jobs:
}
- name: Upload publish output as pipeline artifact
- uses: actions/upload-artifact@v6
+ uses: actions/upload-artifact@v7
with:
name: Publish outputs
path: 'Publish outputs/'
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index d47e077e..fda2b65e 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -18,10 +18,10 @@ jobs:
- name: Setup .NET SDK
uses: actions/setup-dotnet@v5
with:
- dotnet-version: 8.0.100
+ dotnet-version: 8.0.x
- name: Checkout repository
- uses: actions/checkout@v6
+ uses: actions/checkout@v7
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
diff --git a/CHANGES.md b/CHANGES.md
index 8f106dc0..8178e10c 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,12 @@
+# Version 4.0.0
+
+**Breaking Changes**
+* Dropping net6.0 will more easily support trimming [PR #409](https://github.com/microsoft/Microsoft.IO.RecyclableMemoryStream/pull/409)
+* Switch `MemoryStreamDoubleDispose` event level from Critical to Verbose [PR #406](https://github.com/microsoft/Microsoft.IO.RecyclableMemoryStream/pull/406)
+
+**Other Changes**
+* Readme: Add clarity for the large pool of buffers and the GetBuffer method pertaining to the .NET max array length [PR #370](https://github.com/microsoft/Microsoft.IO.RecyclableMemoryStream/pull/370)
+
# Version 3.0.1
**Bug Fix**
diff --git a/README.md b/README.md
index 05869143..b7a2ae36 100644
--- a/README.md
+++ b/README.md
@@ -211,7 +211,7 @@ You can optionally configure the `RecyclableStreamManager.ThrowExceptionOnToArra
| -----|-------|-------------|
| MemoryStreamCreated | Verbose | Logged every time a stream object is allocated. Fields: `guid`, `tag`, `requestedSize`, `actualSize`. |
| MemoryStreamDisposed | Verbose | Logged every time a stream object is disposed. Fields: `guid`, `tag`, `allocationStack`, `disposeStack`. |
-| MemoryStreamDoubleDispose | Critical | Logged if a stream is disposed more than once. This indicates a logic error by the user of the stream. Dispose should happen exactly once per stream to avoid resource usage bugs. Fields: `guid`, `tag`, `allocationStack`, `disposeStack1`, `disposeStack2`. |
+| MemoryStreamDoubleDispose | Verbose | Logged if a stream is disposed more than once. This indicates a logic error by the user of the stream. Dispose should happen exactly once per stream to avoid resource usage bugs. Fields: `guid`, `tag`, `allocationStack`, `disposeStack1`, `disposeStack2`. |
| MemoryStreamFinalized | Error | Logged if a stream has gone out of scope without being disposed. This indicates a resource leak. Fields: `guid`, `tag`, `allocationStack`.|
| MemoryStreamToArray | Verbose | Logged whenever `ToArray` is called. This indicates a potential problem, as calling `ToArray` goes against the concepts of good memory practice which `RecyclableMemoryStream` is trying to solve. Fields: `guid`, `tag`, `stack`, `size`.|
| MemoryStreamManagerInitialized| Informational | Logged when the `RecyclableMemoryStreamManager` is initialized. Fields: `blockSize`, `largeBufferMultiple`, `maximumBufferSize`.|
diff --git a/UnitTests/Tests.cs b/UnitTests/Tests.cs
index 8751a515..c5380b53 100644
--- a/UnitTests/Tests.cs
+++ b/UnitTests/Tests.cs
@@ -4057,9 +4057,8 @@ protected override void TestDroppingLargeBuffer(long maxFreeLargeBufferSize)
}
}
}
-#pragma warning disable 618 // Timeout is obsolete because it kills the thread, which isn't allowed, but it's still handy
- // for tests that are expected to run indefinitely in the failure case.
- [Test, Timeout(10000)]
+
+ [Test, MaxTime(10000)]
public void TryGetBuffer_InfiniteLoop_Issue344()
{
// see https://github.com/microsoft/Microsoft.IO.RecyclableMemoryStream/issues/344
diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj
index 4c0ba6fb..5c3eaa61 100644
--- a/UnitTests/UnitTests.csproj
+++ b/UnitTests/UnitTests.csproj
@@ -9,10 +9,10 @@
NUnit2045
-
-
-
-
+
+
+
+
diff --git a/global.json b/global.json
index ad3aafa3..d1615c2c 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "8.0.416",
+ "version": "8.0.422",
"rollForward": "latestMinor"
}
}
diff --git a/src/Events.cs b/src/Events.cs
index 076685bf..3a4d8799 100644
--- a/src/Events.cs
+++ b/src/Events.cs
@@ -110,7 +110,7 @@ public void MemoryStreamDisposed(Guid guid, string? tag, long lifetimeMs, string
/// Call stack of the first dispose.
/// Call stack of the second dispose.
/// Note: Stacks will only be populated if RecyclableMemoryStreamManager.GenerateCallStacks is true.
- [Event(3, Level = EventLevel.Critical)]
+ [Event(3, Level = EventLevel.Verbose)]
public void MemoryStreamDoubleDispose(Guid guid, string? tag, string? allocationStack, string? disposeStack1,
string? disposeStack2)
{
diff --git a/src/Microsoft.IO.RecyclableMemoryStream.csproj b/src/Microsoft.IO.RecyclableMemoryStream.csproj
index 9b7dda10..5d6a3fdf 100644
--- a/src/Microsoft.IO.RecyclableMemoryStream.csproj
+++ b/src/Microsoft.IO.RecyclableMemoryStream.csproj
@@ -1,13 +1,13 @@
- netstandard2.0;netstandard2.1;net6.0
+ netstandard2.0;netstandard2.1;net8.0
false
false
Microsoft.IO
bin\$(Configuration)\$(TargetFramework)\Microsoft.IO.RecyclableMemoryStream.xml
Microsoft.IO.RecyclableMemoryStream
- 3.0.1
+ 4.0.0-alpha
Microsoft.IO.RecyclableMemoryStream
Microsoft
A pooled MemoryStream allocator to decrease GC load and improve performance on highly scalable systems.
@@ -43,7 +43,7 @@
-
+
diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs
index dc7d6251..2d244776 100644
--- a/src/Properties/AssemblyInfo.cs
+++ b/src/Properties/AssemblyInfo.cs
@@ -33,8 +33,8 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("3.0.1.0")]
-[assembly: AssemblyFileVersion("3.0.1.0")]
+[assembly: AssemblyVersion("4.0.0.0")]
+[assembly: AssemblyFileVersion("4.0.0.0")]
[assembly: CLSCompliant(true)]
diff --git a/src/RecyclableMemoryStream.cs b/src/RecyclableMemoryStream.cs
index 42f16431..27a2064f 100644
--- a/src/RecyclableMemoryStream.cs
+++ b/src/RecyclableMemoryStream.cs
@@ -280,7 +280,7 @@ protected override void Dispose(bool disposing)
if (this.disposed)
{
string? doubleDisposeStack = null;
- if (this.memoryManager.options.GenerateCallStacks)
+ if (this.memoryManager.GenerateDoubleDisposedStackTrace)
{
doubleDisposeStack = Environment.StackTrace;
}
diff --git a/src/RecyclableMemoryStreamManager.cs b/src/RecyclableMemoryStreamManager.cs
index 985309b7..5f8f85f9 100644
--- a/src/RecyclableMemoryStreamManager.cs
+++ b/src/RecyclableMemoryStreamManager.cs
@@ -25,6 +25,7 @@ namespace Microsoft.IO
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+ using System.Diagnostics.Tracing;
using System.Runtime.CompilerServices;
using System.Threading;
@@ -82,6 +83,13 @@ public partial class RecyclableMemoryStreamManager
internal readonly Options options;
+ internal bool GenerateDoubleDisposedStackTrace =>
+ this.options.GenerateCallStacks &&
+ (
+ this.StreamDoubleDisposed != null ||
+ Events.Writer.IsEnabled(EventLevel.Verbose, EventKeywords.None)
+ );
+
///
/// Settings for controlling the behavior of RecyclableMemoryStream
///