This is an automated email from the ASF dual-hosted git repository.

lizhimins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/rocketmq-clients.git


The following commit(s) were added to refs/heads/master by this push:
     new 446f3be2 [C#] Add .NET 10 support and fix build warnings (#1260)
446f3be2 is described below

commit 446f3be20f70044de50b7e197b855395596ec820
Author: zynetYu <[email protected]>
AuthorDate: Tue Jun 9 10:53:39 2026 +0800

    [C#] Add .NET 10 support and fix build warnings (#1260)
    
    Co-authored-by: 张宇 <[email protected]>
---
 csharp/examples/examples.csproj                    |  4 +-
 csharp/rocketmq-client-csharp/MqLogManager.cs      |  7 +--
 csharp/rocketmq-client-csharp/PushConsumer.cs      | 14 ++----
 .../rocketmq-client-csharp.csproj                  | 25 +++++------
 csharp/tests/ClientTest.cs                         |  4 +-
 csharp/tests/ConsumeServiceTest.cs                 | 23 ++++++++--
 csharp/tests/CustomizedBackoffRetryPolicyTest.cs   | 15 +++----
 csharp/tests/ExponentialBackoffRetryPolicyTest.cs  |  9 ++--
 csharp/tests/MessageTest.cs                        | 52 ++++++++--------------
 csharp/tests/ProducerBuilderTest.cs                | 18 +++-----
 csharp/tests/ProducerTest.cs                       | 11 ++---
 csharp/tests/PushConsumerBuilderTest.cs            | 27 ++++-------
 csharp/tests/PushConsumerTest.cs                   |  6 +--
 csharp/tests/SimpleConsumerBuilderTest.cs          | 12 ++---
 csharp/tests/SimpleConsumerTest.cs                 | 15 +++----
 csharp/tests/StatusCheckerTest.cs                  | 26 +++++------
 csharp/tests/TransactionTest.cs                    | 12 ++---
 csharp/tests/tests.csproj                          | 14 +++---
 18 files changed, 121 insertions(+), 173 deletions(-)

diff --git a/csharp/examples/examples.csproj b/csharp/examples/examples.csproj
index 905e6a04..5c32b901 100644
--- a/csharp/examples/examples.csproj
+++ b/csharp/examples/examples.csproj
@@ -3,12 +3,12 @@
         <ProjectReference 
Include="..\rocketmq-client-csharp\rocketmq-client-csharp.csproj" />
     </ItemGroup>
     <ItemGroup>
-      <PackageReference Include="Microsoft.Extensions.Logging.Console" 
Version="6.0.0" />
+      <PackageReference Include="Microsoft.Extensions.Logging.Console" 
Version="10.0.8" />
     </ItemGroup>
 
     <PropertyGroup>
         <OutputType>Exe</OutputType>
-        <TargetFrameworks>net6.0;net8.0</TargetFrameworks>
+        <TargetFrameworks>net8.0;net10.0</TargetFrameworks>
         <ServerGarbageCollection>true</ServerGarbageCollection>
     </PropertyGroup>
 </Project>
diff --git a/csharp/rocketmq-client-csharp/MqLogManager.cs 
b/csharp/rocketmq-client-csharp/MqLogManager.cs
index a6bde949..9a9af59c 100644
--- a/csharp/rocketmq-client-csharp/MqLogManager.cs
+++ b/csharp/rocketmq-client-csharp/MqLogManager.cs
@@ -81,12 +81,9 @@ namespace Org.Apache.Rocketmq
             fileTarget.Layout =
                 new SimpleLayout(
                     "${longdate} ${level:uppercase=true:padding=-5} 
[${processid}] [${threadid}] [${callsite}:${callsite-linenumber}] ${message} 
${onexception:${exception:format=ToString,Data}}");
-            fileTarget.ArchiveFileName =
-                new 
SimpleLayout("${specialfolder:folder=UserProfile}/logs/rocketmq/rocketmq-client.{######}.log");
             fileTarget.ArchiveAboveSize = 67108864;
-            fileTarget.ArchiveNumbering = ArchiveNumberingMode.DateAndSequence;
+            fileTarget.ArchiveSuffixFormat = ".{0:000000}";
             fileTarget.MaxArchiveFiles = fileMaxIndex;
-            fileTarget.ConcurrentWrites = true;
             fileTarget.KeepFileOpen = false;
 
             var asyncTargetWrapper = new AsyncTargetWrapper(fileTarget);
@@ -110,4 +107,4 @@ namespace Org.Apache.Rocketmq
             return loggerFactory;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/csharp/rocketmq-client-csharp/PushConsumer.cs 
b/csharp/rocketmq-client-csharp/PushConsumer.cs
index 1f5364f4..94eeeaef 100644
--- a/csharp/rocketmq-client-csharp/PushConsumer.cs
+++ b/csharp/rocketmq-client-csharp/PushConsumer.cs
@@ -22,7 +22,6 @@ using System.Linq;
 using System.Runtime.CompilerServices;
 using System.Threading;
 using System.Threading.Tasks;
-using System.Threading.Tasks.Schedulers;
 using Apache.Rocketmq.V2;
 using Google.Protobuf.WellKnownTypes;
 using Proto = Apache.Rocketmq.V2;
@@ -92,7 +91,8 @@ namespace Org.Apache.Rocketmq
             _scanAssignmentCts = new CancellationTokenSource();
 
             _processQueueTable = new ConcurrentDictionary<MessageQueue, 
ProcessQueue>();
-            _consumptionTaskScheduler = new 
LimitedConcurrencyLevelTaskScheduler(consumptionThreadCount);
+            _consumptionTaskScheduler =
+                new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 
consumptionThreadCount).ConcurrentScheduler;
             _consumptionCts = new CancellationTokenSource();
 
             _receiveMsgCts = new CancellationTokenSource();
@@ -728,14 +728,6 @@ namespace Org.Apache.Rocketmq
             }
         }
 
-        /// <summary>
-        /// Get the client ID.
-        /// </summary>
-        internal string GetClientId()
-        {
-            return ClientId;
-        }
-
         /// <summary>
         /// Check if the consumer is disposed.
         /// </summary>
@@ -862,4 +854,4 @@ namespace Org.Apache.Rocketmq
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj 
b/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj
index 8d7d8012..d36a3363 100644
--- a/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj
+++ b/csharp/rocketmq-client-csharp/rocketmq-client-csharp.csproj
@@ -6,7 +6,7 @@
 
         <Authors>RocketMQ Authors</Authors>
         <Company>Apache Software Foundation</Company>
-        <TargetFrameworks>net6.0;net8.0;</TargetFrameworks>
+        <TargetFrameworks>net8.0;net10.0</TargetFrameworks>
         <PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
         <RootNamespace>Org.Apache.Rocketmq</RootNamespace>
         <PackageReadmeFile>README.md</PackageReadmeFile>
@@ -23,18 +23,17 @@
     <ItemGroup>
         <None Include="..\README.md" Pack="true" PackagePath="\" />
         <PackageReference Include="Crc32.NET" Version="1.2.0" />
-        <PackageReference Include="Google.Protobuf" Version="3.27.2" />
-        <PackageReference Include="Grpc.Net.Client" Version="2.63.0" />
-        <PackageReference Include="Grpc.Tools" Version="2.64.0">
-            <IncludeAssets>runtime; build; native; contentfiles; analyzers; 
buildtransitive</IncludeAssets>
-            <PrivateAssets>all</PrivateAssets>
-        </PackageReference>
-        <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" 
Version="6.0.0" />
-        <PackageReference Include="NLog.Extensions.Logging" Version="5.3.4" />
-        <PackageReference Include="OpenTelemetry" Version="1.3.1" />
-        <PackageReference Include="OpenTelemetry.Api" Version="1.3.1" />
-        <PackageReference 
Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.3.1" />
-        <PackageReference Include="ParallelExtensionsExtras" Version="1.2.0" />
+        <PackageReference Include="Google.Protobuf" Version="3.35.0" />
+        <PackageReference Include="Grpc.Net.Client" Version="2.80.0" />
+        <PackageReference Include="Grpc.Tools" Version="2.81.0">
+            <IncludeAssets>runtime; build; native; contentfiles; analyzers; 
buildtransitive</IncludeAssets>
+            <PrivateAssets>all</PrivateAssets>
+        </PackageReference>
+        <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" 
Version="10.0.8" />
+        <PackageReference Include="NLog.Extensions.Logging" Version="6.1.3" />
+        <PackageReference Include="OpenTelemetry" Version="1.15.3" />
+        <PackageReference Include="OpenTelemetry.Api" Version="1.15.3" />
+        <PackageReference 
Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.3" />
 
         <Protobuf Include="..\..\protos\apache\rocketmq\v2\definition.proto" 
ProtoRoot="..\..\protos" GrpcServices="Client" />
         <Protobuf Include="..\..\protos\apache\rocketmq\v2\service.proto" 
ProtoRoot="..\..\protos" GrpcServices="Both" />
diff --git a/csharp/tests/ClientTest.cs b/csharp/tests/ClientTest.cs
index 8fdfa861..e428137e 100644
--- a/csharp/tests/ClientTest.cs
+++ b/csharp/tests/ClientTest.cs
@@ -100,7 +100,7 @@ namespace tests
                 await testClient.OnTopicRouteDataFetched("testTopic", 
topicRouteData);
                 Assert.Fail();
             }
-            catch (Exception e)
+            catch (Exception)
             {
                 mockClientManager.Verify(cm => 
cm.Telemetry(It.IsAny<Endpoints>()), Times.Once);
             }
@@ -164,4 +164,4 @@ namespace tests
             public T Current => throw new NotImplementedException();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/csharp/tests/ConsumeServiceTest.cs 
b/csharp/tests/ConsumeServiceTest.cs
index 8ef757e4..469ac2e0 100644
--- a/csharp/tests/ConsumeServiceTest.cs
+++ b/csharp/tests/ConsumeServiceTest.cs
@@ -21,7 +21,6 @@ using System.Linq;
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
-using System.Threading.Tasks.Schedulers;
 using Google.Protobuf;
 using Google.Protobuf.WellKnownTypes;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -97,7 +96,7 @@ namespace tests
         private TestConsumeService CreateService(IMessageListener 
messageListener)
         {
             return new TestConsumeService("testClientId", messageListener,
-                new CurrentThreadTaskScheduler(), new CancellationToken());
+                new InlineTaskScheduler(), new CancellationToken());
         }
 
         private class TestSuccessMessageListener : IMessageListener
@@ -123,6 +122,24 @@ namespace tests
 
             public override void Consume(ProcessQueue pq, List<MessageView> 
messageViews) => Task.FromResult(0);
         }
+
+        private sealed class InlineTaskScheduler : TaskScheduler
+        {
+            protected override IEnumerable<Task> GetScheduledTasks()
+            {
+                return Enumerable.Empty<Task>();
+            }
+
+            protected override void QueueTask(Task task)
+            {
+                TryExecuteTask(task);
+            }
+
+            protected override bool TryExecuteTaskInline(Task task, bool 
taskWasPreviouslyQueued)
+            {
+                return TryExecuteTask(task);
+            }
+        }
     }
 
-}
\ No newline at end of file
+}
diff --git a/csharp/tests/CustomizedBackoffRetryPolicyTest.cs 
b/csharp/tests/CustomizedBackoffRetryPolicyTest.cs
index dcbd4e3e..561f353e 100644
--- a/csharp/tests/CustomizedBackoffRetryPolicyTest.cs
+++ b/csharp/tests/CustomizedBackoffRetryPolicyTest.cs
@@ -40,10 +40,9 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestConstructWithEmptyDurations()
         {
-            new CustomizedBackoffRetryPolicy(new List<TimeSpan>(), 3);
+            Assert.ThrowsExactly<ArgumentException>(() => new 
CustomizedBackoffRetryPolicy(new List<TimeSpan>(), 3));
         }
 
         [TestMethod]
@@ -59,19 +58,17 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestGetNextAttemptDelayWithInvalidAttempt()
         {
             var policy = new CustomizedBackoffRetryPolicy(new List<TimeSpan> { 
TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2) }, 3);
-            policy.GetNextAttemptDelay(0);
+            Assert.ThrowsExactly<ArgumentException>(() => 
policy.GetNextAttemptDelay(0));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestGetNextAttemptDelayWithNegativeAttempt()
         {
             var policy = new CustomizedBackoffRetryPolicy(new List<TimeSpan> { 
TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2) }, 3);
-            policy.GetNextAttemptDelay(-1);
+            Assert.ThrowsExactly<ArgumentException>(() => 
policy.GetNextAttemptDelay(-1));
         }
 
         [TestMethod]
@@ -95,7 +92,6 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestFromProtobufWithInvalidRetryPolicy()
         {
             var retryPolicy = new RetryPolicy
@@ -108,7 +104,7 @@ namespace tests
                     Multiplier = 1.0f
                 }
             };
-            CustomizedBackoffRetryPolicy.FromProtobuf(retryPolicy);
+            Assert.ThrowsExactly<ArgumentException>(() => 
CustomizedBackoffRetryPolicy.FromProtobuf(retryPolicy));
         }
 
         [TestMethod]
@@ -152,7 +148,6 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(InvalidOperationException))]
         public void TestInheritBackoffWithInvalidPolicy()
         {
             var policy = new CustomizedBackoffRetryPolicy(new List<TimeSpan>
@@ -165,7 +160,7 @@ namespace tests
             {
                 ExponentialBackoff = new ExponentialBackoff()
             };
-            policy.InheritBackoff(retryPolicy);
+            Assert.ThrowsExactly<InvalidOperationException>(() => 
policy.InheritBackoff(retryPolicy));
         }
     }
 }
\ No newline at end of file
diff --git a/csharp/tests/ExponentialBackoffRetryPolicyTest.cs 
b/csharp/tests/ExponentialBackoffRetryPolicyTest.cs
index 70b3254f..a4869313 100644
--- a/csharp/tests/ExponentialBackoffRetryPolicyTest.cs
+++ b/csharp/tests/ExponentialBackoffRetryPolicyTest.cs
@@ -42,11 +42,10 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestGetNextAttemptDelayWithIllegalAttempt()
         {
             var retryPolicy = new ExponentialBackoffRetryPolicy(maxAttempts, 
initialBackoff, maxBackoff, backoffMultiplier);
-            retryPolicy.GetNextAttemptDelay(0);
+            Assert.ThrowsExactly<ArgumentException>(() => 
retryPolicy.GetNextAttemptDelay(0));
         }
 
         [TestMethod]
@@ -87,7 +86,6 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestFromProtobufWithoutExponentialBackoff()
         {
             var customizedBackoff = new CustomizedBackoff();
@@ -96,7 +94,7 @@ namespace tests
                 MaxAttempts = maxAttempts,
                 CustomizedBackoff = customizedBackoff
             };
-            ExponentialBackoffRetryPolicy.FromProtobuf(retryPolicyProto);
+            Assert.ThrowsExactly<ArgumentException>(() => 
ExponentialBackoffRetryPolicy.FromProtobuf(retryPolicyProto));
         }
 
         [TestMethod]
@@ -149,7 +147,6 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(InvalidOperationException))]
         public void TestInheritBackoffWithoutExponentialBackoff()
         {
             var customizedBackoff = new CustomizedBackoff();
@@ -160,7 +157,7 @@ namespace tests
             };
 
             var exponentialBackoffRetryPolicy = new 
ExponentialBackoffRetryPolicy(maxAttempts, initialBackoff, maxBackoff, 
backoffMultiplier);
-            exponentialBackoffRetryPolicy.InheritBackoff(retryPolicyProto);
+            Assert.ThrowsExactly<InvalidOperationException>(() => 
exponentialBackoffRetryPolicy.InheritBackoff(retryPolicyProto));
         }
     }
 
diff --git a/csharp/tests/MessageTest.cs b/csharp/tests/MessageTest.cs
index 56d942cf..e29570b1 100644
--- a/csharp/tests/MessageTest.cs
+++ b/csharp/tests/MessageTest.cs
@@ -27,96 +27,83 @@ namespace tests
     public class MessageTest
     {
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalTopic0()
         {
             const string topic = null;
-            new Message.Builder().SetTopic(topic);
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetTopic(topic));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalTopic1()
         {
             const string topic = "";
-            new Message.Builder().SetTopic(topic);
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetTopic(topic));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalTag0()
         {
-            new Message.Builder().SetTag(null);
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetTag(null));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalTag1()
         {
-            new Message.Builder().SetTag("");
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetTag(""));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalTag2()
         {
-            new Message.Builder().SetTag("\t");
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetTag("\t"));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalTag3()
         {
-            new Message.Builder().SetTag("\t\n");
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetTag("\t\n"));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalTag4()
         {
-            new Message.Builder().SetTag("abc|cde");
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetTag("abc|cde"));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalMessageGroup0()
         {
-            new Message.Builder().SetMessageGroup(null);
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetMessageGroup(null));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalMessageGroup1()
         {
-            new Message.Builder().SetMessageGroup("");
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetMessageGroup(""));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalMessageGroup2()
         {
-            new Message.Builder().SetMessageGroup("\t");
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetMessageGroup("\t"));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalMessageGroup3()
         {
-            new Message.Builder().SetMessageGroup("\t\n");
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetMessageGroup("\t\n"));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalProperty0()
         {
-            new Message.Builder().AddProperty(null, "b");
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().AddProperty(null, "b"));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalProperty1()
         {
-            new Message.Builder().AddProperty("a", null);
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().AddProperty("a", null));
         }
 
         [TestMethod]
@@ -136,10 +123,9 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestIllegalKey()
         {
-            new Message.Builder().SetKeys("\t");
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetKeys("\t"));
         }
 
         [TestMethod]
@@ -174,20 +160,18 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestSetDeliveryTimestampAndMessageGroup()
         {
-            new Message.Builder().SetDeliveryTimestamp(DateTime.UtcNow + 
TimeSpan.FromSeconds(30))
-                .SetMessageGroup("messageGroup").Build();
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetDeliveryTimestamp(DateTime.UtcNow + 
TimeSpan.FromSeconds(30))
+                .SetMessageGroup("messageGroup").Build());
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestSetMessageGroupAndDeliveryTimestamp()
         {
-            new Message.Builder().SetMessageGroup("messageGroup")
+            Assert.ThrowsExactly<ArgumentException>(() => new 
Message.Builder().SetMessageGroup("messageGroup")
                 .SetDeliveryTimestamp(DateTime.UtcNow + 
TimeSpan.FromSeconds(30))
-                .Build();
+                .Build());
         }
     }
 }
\ No newline at end of file
diff --git a/csharp/tests/ProducerBuilderTest.cs 
b/csharp/tests/ProducerBuilderTest.cs
index c318aaf1..b37ec2d9 100644
--- a/csharp/tests/ProducerBuilderTest.cs
+++ b/csharp/tests/ProducerBuilderTest.cs
@@ -26,27 +26,24 @@ namespace tests
     public class ProducerBuilderTest
     {
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestSetClientConfigurationWithNull()
         {
             var builder = new Producer.Builder();
-            builder.SetClientConfig(null);
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetClientConfig(null));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(NullReferenceException))]
         public void TestSetTopicWithNull()
         {
             var builder = new Producer.Builder();
-            builder.SetTopics(null);
+            Assert.ThrowsExactly<NullReferenceException>(() => 
builder.SetTopics(null));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestSetIllegalTopic()
         {
             var builder = new Producer.Builder();
-            builder.SetTopics("\t");
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetTopics("\t"));
         }
 
         [TestMethod]
@@ -57,11 +54,10 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestSetNegativeMaxAttempts()
         {
             var builder = new Producer.Builder();
-            builder.SetMaxAttempts(-1);
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetMaxAttempts(-1));
         }
 
         [TestMethod]
@@ -72,11 +68,10 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestSetTransactionCheckerWithNull()
         {
             var builder = new Producer.Builder();
-            builder.SetTransactionChecker(null);
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetTransactionChecker(null));
         }
 
         [TestMethod]
@@ -87,11 +82,10 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public async Task TestBuildWithoutClientConfiguration()
         {
             var builder = new Producer.Builder();
-            await builder.Build();
+            await Assert.ThrowsExactlyAsync<ArgumentException>(async () => 
await builder.Build());
         }
 
         [TestMethod]
diff --git a/csharp/tests/ProducerTest.cs b/csharp/tests/ProducerTest.cs
index 8fe53000..2857396a 100644
--- a/csharp/tests/ProducerTest.cs
+++ b/csharp/tests/ProducerTest.cs
@@ -32,7 +32,6 @@ namespace tests
     public class ProducerTest
     {
         [TestMethod]
-        [ExpectedException(typeof(InvalidOperationException))]
         public async Task TestSendBeforeStartup()
         {
             var clientConfig = new 
ClientConfig.Builder().SetEndpoints("127.0.0.1:9876").Build();
@@ -40,7 +39,7 @@ namespace tests
             publishingTopics.TryAdd("testTopic", true);
             var producer = new Producer(clientConfig, publishingTopics, 1, 
null);
             var message = new 
Message.Builder().SetTopic("testTopic").SetBody(Encoding.UTF8.GetBytes("foobar")).Build();
-            await producer.Send(message);
+            await Assert.ThrowsExactlyAsync<InvalidOperationException>(async 
() => await producer.Send(message));
         }
 
         [TestMethod]
@@ -79,7 +78,6 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public async Task TestSendFailureWithTopic()
         {
             var producer = CreateTestClient();
@@ -90,7 +88,7 @@ namespace tests
             var exception = new ArgumentException();
             mockClientManager.Setup(cm => cm.SendMessage(It.IsAny<Endpoints>(),
                 It.IsAny<Proto.SendMessageRequest>(), 
It.IsAny<TimeSpan>())).Throws(exception);
-            await producer.Send(message);
+            await Assert.ThrowsExactlyAsync<ArgumentException>(async () => 
await producer.Send(message));
             var maxAttempts = 
producer.PublishingSettings.GetRetryPolicy().GetMaxAttempts();
             mockClientManager.Verify(cm => 
cm.SendMessage(It.IsAny<Endpoints>(),
                 It.IsAny<Proto.SendMessageRequest>(), It.IsAny<TimeSpan>()), 
Times.Exactly(maxAttempts));
@@ -123,7 +121,6 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public async Task TestRecallFailure()
         {
             var producer = CreateTestClient();
@@ -133,7 +130,7 @@ namespace tests
             var exception = new ArgumentException();
             mockClientManager.Setup(cm => 
cm.RecallMessage(It.IsAny<Endpoints>(),
                 It.IsAny<Proto.RecallMessageRequest>(), 
It.IsAny<TimeSpan>())).Throws(exception);
-            await producer.RecallMessage("testTopic", "handle");
+            await Assert.ThrowsExactlyAsync<ArgumentException>(async () => 
await producer.RecallMessage("testTopic", "handle"));
             mockClientManager.Verify(cm => 
cm.RecallMessage(It.IsAny<Endpoints>(),
                 It.IsAny<Proto.RecallMessageRequest>(), It.IsAny<TimeSpan>()), 
Times.Once);
         }
@@ -179,4 +176,4 @@ namespace tests
             return producer;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/csharp/tests/PushConsumerBuilderTest.cs 
b/csharp/tests/PushConsumerBuilderTest.cs
index ba33a1a2..b1aaeea8 100644
--- a/csharp/tests/PushConsumerBuilderTest.cs
+++ b/csharp/tests/PushConsumerBuilderTest.cs
@@ -27,75 +27,66 @@ namespace tests
     public class PushConsumerBuilderTest
     {
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestSetClientConfigWithNull()
         {
             var builder = new PushConsumer.Builder();
-            builder.SetClientConfig(null);
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetClientConfig(null));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestSetConsumerGroupWithNull()
         {
             var builder = new PushConsumer.Builder();
-            builder.SetConsumerGroup(null);
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetConsumerGroup(null));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestSetConsumerGroupWithSpecialChar()
         {
             var builder = new PushConsumer.Builder();
-            builder.SetConsumerGroup("#.testGroup#");
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetConsumerGroup("#.testGroup#"));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestBuildWithoutExpressions()
         {
             var builder = new PushConsumer.Builder();
-            builder.SetSubscriptionExpression(null);
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetSubscriptionExpression(null));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestBuildWithEmptyExpressions()
         {
             var builder = new PushConsumer.Builder();
-            builder.SetSubscriptionExpression(new Dictionary<string, 
FilterExpression>());
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetSubscriptionExpression(new Dictionary<string, FilterExpression>()));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestBuildWithNullMessageListener()
         {
             var builder = new PushConsumer.Builder();
-            builder.SetMessageListener(null);
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetMessageListener(null));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestNegativeMaxCacheMessageCount()
         {
             var builder = new PushConsumer.Builder();
-            builder.SetMaxCacheMessageCount(-1);
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetMaxCacheMessageCount(-1));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestNegativeMaxCacheMessageSizeInBytes()
         {
             var builder = new PushConsumer.Builder();
-            builder.SetMaxCacheMessageSizeInBytes(-1);
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetMaxCacheMessageSizeInBytes(-1));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestNegativeConsumptionThreadCount()
         {
             var builder = new PushConsumer.Builder();
-            builder.SetMaxCacheMessageCount(-1);
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetMaxCacheMessageCount(-1));
         }
 
         [TestMethod]
diff --git a/csharp/tests/PushConsumerTest.cs b/csharp/tests/PushConsumerTest.cs
index c8a383c9..75040075 100644
--- a/csharp/tests/PushConsumerTest.cs
+++ b/csharp/tests/PushConsumerTest.cs
@@ -31,19 +31,17 @@ namespace tests
     public class PushConsumerTest
     {
         [TestMethod]
-        [ExpectedException(typeof(InvalidOperationException))]
         public async Task TestSubscribeBeforeStartup()
         {
             var pushConsumer = CreatePushConsumer();
-            await pushConsumer.Subscribe("testTopic", new 
FilterExpression("*"));
+            await Assert.ThrowsExactlyAsync<InvalidOperationException>(async 
() => await pushConsumer.Subscribe("testTopic", new FilterExpression("*")));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(InvalidOperationException))]
         public void TestUnsubscribeBeforeStartup()
         {
             var pushConsumer = CreatePushConsumer();
-            pushConsumer.Unsubscribe("testTopic");
+            Assert.ThrowsExactly<InvalidOperationException>(() => 
pushConsumer.Unsubscribe("testTopic"));
         }
 
         [TestMethod]
diff --git a/csharp/tests/SimpleConsumerBuilderTest.cs 
b/csharp/tests/SimpleConsumerBuilderTest.cs
index 1031f911..decbfdab 100644
--- a/csharp/tests/SimpleConsumerBuilderTest.cs
+++ b/csharp/tests/SimpleConsumerBuilderTest.cs
@@ -26,19 +26,17 @@ namespace tests
     public class SimpleConsumerBuilderTest
     {
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestSetClientConfigurationWithNull()
         {
             var builder = new SimpleConsumer.Builder();
-            builder.SetClientConfig(null);
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetClientConfig(null));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestSetConsumerGroupWithNull()
         {
             var builder = new SimpleConsumer.Builder();
-            builder.SetConsumerGroup(null);
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetConsumerGroup(null));
         }
 
         [TestMethod]
@@ -49,19 +47,17 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestBuildWithEmptyExpressions()
         {
             var builder = new SimpleConsumer.Builder();
-            builder.SetSubscriptionExpression(new Dictionary<string, 
FilterExpression>());
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetSubscriptionExpression(new Dictionary<string, FilterExpression>()));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestBuildWithoutExpressions()
         {
             var builder = new SimpleConsumer.Builder();
-            builder.SetSubscriptionExpression(null);
+            Assert.ThrowsExactly<ArgumentException>(() => 
builder.SetSubscriptionExpression(null));
         }
 
         [TestMethod]
diff --git a/csharp/tests/SimpleConsumerTest.cs 
b/csharp/tests/SimpleConsumerTest.cs
index b8ea64b3..68c31175 100644
--- a/csharp/tests/SimpleConsumerTest.cs
+++ b/csharp/tests/SimpleConsumerTest.cs
@@ -58,45 +58,40 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(InvalidOperationException))]
         public async Task TestReceiveWithoutStart()
         {
             var consumer = CreateSimpleConsumer();
-            await consumer.Receive(16, TimeSpan.FromSeconds(15));
+            await Assert.ThrowsExactlyAsync<InvalidOperationException>(async 
() => await consumer.Receive(16, TimeSpan.FromSeconds(15)));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(InvalidOperationException))]
         public async Task TestAckWithoutStart()
         {
             var consumer = CreateSimpleConsumer();
             var messageView = MessageView.FromProtobuf(CreateMessage());
-            await consumer.Ack(messageView);
+            await Assert.ThrowsExactlyAsync<InvalidOperationException>(async 
() => await consumer.Ack(messageView));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(InvalidOperationException))]
         public async Task TestSubscribeWithoutStart()
         {
             var consumer = CreateSimpleConsumer();
-            await consumer.Subscribe("testTopic", new FilterExpression("*"));
+            await Assert.ThrowsExactlyAsync<InvalidOperationException>(async 
() => await consumer.Subscribe("testTopic", new FilterExpression("*")));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(InvalidOperationException))]
         public void TestUnsubscribeWithoutStart()
         {
             var consumer = CreateSimpleConsumer();
-            consumer.Unsubscribe("testTopic");
+            Assert.ThrowsExactly<InvalidOperationException>(() => 
consumer.Unsubscribe("testTopic"));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(InternalErrorException))]
         public async Task TestReceiveWithZeroMaxMessageNum()
         {
             var consumer = CreateSimpleConsumer();
             consumer.State = State.Running;
-            await consumer.Receive(0, TimeSpan.FromSeconds(15));
+            await Assert.ThrowsExactlyAsync<InternalErrorException>(async () 
=> await consumer.Receive(0, TimeSpan.FromSeconds(15)));
         }
 
         [TestMethod]
diff --git a/csharp/tests/StatusCheckerTest.cs 
b/csharp/tests/StatusCheckerTest.cs
index b64ccc77..6103aa4e 100644
--- a/csharp/tests/StatusCheckerTest.cs
+++ b/csharp/tests/StatusCheckerTest.cs
@@ -73,7 +73,7 @@ namespace tests
             var request = new Proto.ReceiveMessageRequest();
             var requestId = "requestId";
 
-            Assert.ThrowsException<BadRequestException>(() => 
StatusChecker.Check(status, request, requestId));
+            Assert.ThrowsExactly<BadRequestException>(() => 
StatusChecker.Check(status, request, requestId));
         }
 
         [TestMethod]
@@ -83,7 +83,7 @@ namespace tests
             var request = new Proto.ReceiveMessageRequest();
             var requestId = "requestId";
 
-            Assert.ThrowsException<UnauthorizedException>(() => 
StatusChecker.Check(status, request, requestId));
+            Assert.ThrowsExactly<UnauthorizedException>(() => 
StatusChecker.Check(status, request, requestId));
         }
 
         [TestMethod]
@@ -93,7 +93,7 @@ namespace tests
             var request = new Proto.ReceiveMessageRequest();
             var requestId = "requestId";
 
-            Assert.ThrowsException<PaymentRequiredException>(() => 
StatusChecker.Check(status, request, requestId));
+            Assert.ThrowsExactly<PaymentRequiredException>(() => 
StatusChecker.Check(status, request, requestId));
         }
 
         [TestMethod]
@@ -103,7 +103,7 @@ namespace tests
             var request = new Proto.ReceiveMessageRequest();
             var requestId = "requestId";
 
-            Assert.ThrowsException<ForbiddenException>(() => 
StatusChecker.Check(status, request, requestId));
+            Assert.ThrowsExactly<ForbiddenException>(() => 
StatusChecker.Check(status, request, requestId));
         }
 
         [TestMethod]
@@ -113,7 +113,7 @@ namespace tests
             var request = new Proto.SendMessageRequest();
             var requestId = "requestId";
 
-            Assert.ThrowsException<NotFoundException>(() => 
StatusChecker.Check(status, request, requestId));
+            Assert.ThrowsExactly<NotFoundException>(() => 
StatusChecker.Check(status, request, requestId));
         }
 
         [TestMethod]
@@ -123,7 +123,7 @@ namespace tests
             var request = new Proto.ReceiveMessageRequest();
             var requestId = "requestId";
 
-            Assert.ThrowsException<NotFoundException>(() => 
StatusChecker.Check(status, request, requestId));
+            Assert.ThrowsExactly<NotFoundException>(() => 
StatusChecker.Check(status, request, requestId));
         }
 
         [TestMethod]
@@ -133,7 +133,7 @@ namespace tests
             var request = new Proto.ReceiveMessageRequest();
             var requestId = "requestId";
 
-            Assert.ThrowsException<PayloadTooLargeException>(() => 
StatusChecker.Check(status, request, requestId));
+            Assert.ThrowsExactly<PayloadTooLargeException>(() => 
StatusChecker.Check(status, request, requestId));
         }
 
         [TestMethod]
@@ -143,7 +143,7 @@ namespace tests
             var request = new Proto.ReceiveMessageRequest();
             var requestId = "requestId";
 
-            Assert.ThrowsException<TooManyRequestsException>(() => 
StatusChecker.Check(status, request, requestId));
+            Assert.ThrowsExactly<TooManyRequestsException>(() => 
StatusChecker.Check(status, request, requestId));
         }
 
         [TestMethod]
@@ -153,7 +153,7 @@ namespace tests
             var request = new Proto.ReceiveMessageRequest();
             var requestId = "requestId";
 
-            Assert.ThrowsException<RequestHeaderFieldsTooLargeException>(() => 
StatusChecker.Check(status, request, requestId));
+            Assert.ThrowsExactly<RequestHeaderFieldsTooLargeException>(() => 
StatusChecker.Check(status, request, requestId));
         }
 
         [TestMethod]
@@ -163,7 +163,7 @@ namespace tests
             var request = new Proto.ReceiveMessageRequest();
             var requestId = "requestId";
 
-            Assert.ThrowsException<InternalErrorException>(() => 
StatusChecker.Check(status, request, requestId));
+            Assert.ThrowsExactly<InternalErrorException>(() => 
StatusChecker.Check(status, request, requestId));
         }
 
         [TestMethod]
@@ -173,7 +173,7 @@ namespace tests
             var request = new Proto.ReceiveMessageRequest();
             var requestId = "requestId";
 
-            Assert.ThrowsException<ProxyTimeoutException>(() => 
StatusChecker.Check(status, request, requestId));
+            Assert.ThrowsExactly<ProxyTimeoutException>(() => 
StatusChecker.Check(status, request, requestId));
         }
 
         [TestMethod]
@@ -183,7 +183,7 @@ namespace tests
             var request = new Proto.ReceiveMessageRequest();
             var requestId = "requestId";
 
-            Assert.ThrowsException<UnsupportedException>(() => 
StatusChecker.Check(status, request, requestId));
+            Assert.ThrowsExactly<UnsupportedException>(() => 
StatusChecker.Check(status, request, requestId));
         }
 
         [TestMethod]
@@ -193,7 +193,7 @@ namespace tests
             var request = new Proto.ReceiveMessageRequest();
             var requestId = "requestId";
 
-            Assert.ThrowsException<UnsupportedException>(() => 
StatusChecker.Check(status, request, requestId));
+            Assert.ThrowsExactly<UnsupportedException>(() => 
StatusChecker.Check(status, request, requestId));
         }
     }
 }
\ No newline at end of file
diff --git a/csharp/tests/TransactionTest.cs b/csharp/tests/TransactionTest.cs
index 231acd2d..fb7a3115 100644
--- a/csharp/tests/TransactionTest.cs
+++ b/csharp/tests/TransactionTest.cs
@@ -57,13 +57,12 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestTryAddExceededMessages()
         {
             var transaction = new Transaction(_producer);
             var message = CreateMessage();
             transaction.TryAddMessage(message);
-            transaction.TryAddMessage(message);
+            Assert.ThrowsExactly<ArgumentException>(() => 
transaction.TryAddMessage(message));
         }
 
         [TestMethod]
@@ -79,7 +78,6 @@ namespace tests
         }
 
         [TestMethod]
-        [ExpectedException(typeof(ArgumentException))]
         public void TestTryAddReceiptNotContained()
         {
             var transaction = new Transaction(_producer);
@@ -90,23 +88,21 @@ namespace tests
             var mq0 = CreateMessageQueue();
 
             var sendReceipt = CreateSendReceipt(mq0);
-            transaction.TryAddReceipt(publishingMessage, sendReceipt.First());
+            Assert.ThrowsExactly<ArgumentException>(() => 
transaction.TryAddReceipt(publishingMessage, sendReceipt.First()));
         }
 
         [TestMethod]
-        [ExpectedException(typeof(InvalidOperationException))]
         public async Task TestCommitWithNoReceipts()
         {
             var transaction = new Transaction(_producer);
-            await transaction.Commit();
+            await Assert.ThrowsExactlyAsync<InvalidOperationException>(async 
() => await transaction.Commit());
         }
 
         [TestMethod]
-        [ExpectedException(typeof(InvalidOperationException))]
         public async Task TestRollbackWithNoReceipts()
         {
             var transaction = new Transaction(_producer);
-            await transaction.Rollback();
+            await Assert.ThrowsExactlyAsync<InvalidOperationException>(async 
() => await transaction.Rollback());
         }
 
         [TestMethod]
diff --git a/csharp/tests/tests.csproj b/csharp/tests/tests.csproj
index 6cb51b32..3db19e63 100644
--- a/csharp/tests/tests.csproj
+++ b/csharp/tests/tests.csproj
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFrameworks>net8.0</TargetFrameworks>
+    <TargetFrameworks>net10.0</TargetFrameworks>
 
     <IsPackable>false</IsPackable>
   </PropertyGroup>
@@ -9,12 +9,12 @@
   <ItemGroup>
     <PackageReference Include="Contrib.Grpc.Core.M1" Version="2.46.7" />
     <PackageReference Include="Grpc.Core" Version="2.46.6" />
-    <PackageReference Include="Microsoft.Extensions.Logging.Console" 
Version="8.0.0" />
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
-    <PackageReference Include="Moq" Version="4.20.70" />
-    <PackageReference Include="MSTest.TestAdapter" Version="3.4.3" />
-    <PackageReference Include="MSTest.TestFramework" Version="3.4.3" />
-    <PackageReference Include="coverlet.collector" Version="6.0.2">
+    <PackageReference Include="Microsoft.Extensions.Logging.Console" 
Version="10.0.8" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.6.0" />
+    <PackageReference Include="Moq" Version="4.20.72" />
+    <PackageReference Include="MSTest.TestAdapter" Version="3.11.1" />
+    <PackageReference Include="MSTest.TestFramework" Version="3.11.1" />
+    <PackageReference Include="coverlet.collector" Version="10.0.1">
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; 
buildtransitive</IncludeAssets>
     </PackageReference>


Reply via email to