diff --git a/src/BootstrapBlazor/Services/TcpSocket/DataPackage/DataPackageHandlerBase.cs b/src/BootstrapBlazor/Services/TcpSocket/DataPackage/DataPackageHandlerBase.cs index cba5c6e3156..e3040ba0e3d 100644 --- a/src/BootstrapBlazor/Services/TcpSocket/DataPackage/DataPackageHandlerBase.cs +++ b/src/BootstrapBlazor/Services/TcpSocket/DataPackage/DataPackageHandlerBase.cs @@ -18,7 +18,7 @@ public abstract class DataPackageHandlerBase : IDataPackageHandler /// /// 当接收数据处理完成后,回调该函数执行接收 /// - public Func, Task>? ReceivedCallBack { get; set; } + public Func, ValueTask>? ReceivedCallBack { get; set; } /// /// Sends the specified data asynchronously to the target destination. @@ -29,9 +29,9 @@ public abstract class DataPackageHandlerBase : IDataPackageHandler /// The data to be sent, represented as a block of memory. /// A task that represents the asynchronous operation. The task result contains a of representing the response or acknowledgment received from the target destination. - public virtual Task> SendAsync(Memory data) + public virtual ValueTask> SendAsync(ReadOnlyMemory data) { - return Task.FromResult(data); + return ValueTask.FromResult(data); } /// @@ -39,9 +39,9 @@ public virtual Task> SendAsync(Memory data) /// /// A memory buffer containing the data to be processed. The buffer must not be empty. /// A task that represents the asynchronous operation. - public virtual Task ReceiveAsync(Memory data) + public virtual ValueTask ReceiveAsync(ReadOnlyMemory data) { - return Task.CompletedTask; + return ValueTask.CompletedTask; } /// @@ -52,7 +52,7 @@ public virtual Task ReceiveAsync(Memory data) /// for the specified . /// The memory buffer containing the data to process. /// The length of the valid data within the buffer. - protected void SlicePackage(Memory buffer, int length) + protected void SlicePackage(ReadOnlyMemory buffer, int length) { _lastReceiveBuffer = buffer[length..].ToArray().AsMemory(); } @@ -66,7 +66,7 @@ protected void SlicePackage(Memory buffer, int length) /// The buffer to concatenate with the previously stored data. Must not be empty. /// A instance containing the concatenated data. If no previously stored data exists, the /// method returns the input . - protected Memory ConcatBuffer(Memory buffer) + protected ReadOnlyMemory ConcatBuffer(ReadOnlyMemory buffer) { if (_lastReceiveBuffer.IsEmpty) { diff --git a/src/BootstrapBlazor/Services/TcpSocket/DataPackage/DelimiterDataPackageHandler.cs b/src/BootstrapBlazor/Services/TcpSocket/DataPackage/DelimiterDataPackageHandler.cs index 22e6a042495..0de2d040195 100644 --- a/src/BootstrapBlazor/Services/TcpSocket/DataPackage/DelimiterDataPackageHandler.cs +++ b/src/BootstrapBlazor/Services/TcpSocket/DataPackage/DelimiterDataPackageHandler.cs @@ -51,7 +51,7 @@ public DelimiterDataPackageHandler(byte[] delimiter) /// /// /// - public override async Task ReceiveAsync(Memory data) + public override async ValueTask ReceiveAsync(ReadOnlyMemory data) { data = ConcatBuffer(data); diff --git a/src/BootstrapBlazor/Services/TcpSocket/DataPackage/FixLengthDataPackageHandler.cs b/src/BootstrapBlazor/Services/TcpSocket/DataPackage/FixLengthDataPackageHandler.cs index 798c95d0815..e20458edde2 100644 --- a/src/BootstrapBlazor/Services/TcpSocket/DataPackage/FixLengthDataPackageHandler.cs +++ b/src/BootstrapBlazor/Services/TcpSocket/DataPackage/FixLengthDataPackageHandler.cs @@ -23,7 +23,7 @@ public class FixLengthDataPackageHandler(int length) : DataPackageHandlerBase /// /// /// - public override async Task ReceiveAsync(Memory data) + public override async ValueTask ReceiveAsync(ReadOnlyMemory data) { while (data.Length > 0) { diff --git a/src/BootstrapBlazor/Services/TcpSocket/DataPackage/IDataPackageHandler.cs b/src/BootstrapBlazor/Services/TcpSocket/DataPackage/IDataPackageHandler.cs index 89c9f13d0be..b6b5eb2e10a 100644 --- a/src/BootstrapBlazor/Services/TcpSocket/DataPackage/IDataPackageHandler.cs +++ b/src/BootstrapBlazor/Services/TcpSocket/DataPackage/IDataPackageHandler.cs @@ -16,7 +16,7 @@ public interface IDataPackageHandler /// /// Gets or sets the callback function to be invoked when data is received asynchronously. /// - Func, Task>? ReceivedCallBack { get; set; } + Func, ValueTask>? ReceivedCallBack { get; set; } /// /// Sends the specified data asynchronously to the target destination. @@ -27,7 +27,7 @@ public interface IDataPackageHandler /// The data to be sent, represented as a block of memory. /// A task that represents the asynchronous operation. The task result contains a of representing the response or acknowledgment received from the target destination. - Task> SendAsync(Memory data); + ValueTask> SendAsync(ReadOnlyMemory data); /// /// Asynchronously receives data from a source and writes it into the provided memory buffer. @@ -37,5 +37,5 @@ public interface IDataPackageHandler /// The memory buffer to store the received data. The buffer must be writable and have sufficient capacity. /// A task that represents the asynchronous operation. The task result contains the number of bytes written to the /// buffer. Returns 0 if the end of the data stream is reached. - Task ReceiveAsync(Memory data); + ValueTask ReceiveAsync(ReadOnlyMemory data); } diff --git a/src/BootstrapBlazor/Services/TcpSocket/DefaultTcpSocketClient.cs b/src/BootstrapBlazor/Services/TcpSocket/DefaultTcpSocketClient.cs index 3701ac82f18..84b3f462393 100644 --- a/src/BootstrapBlazor/Services/TcpSocket/DefaultTcpSocketClient.cs +++ b/src/BootstrapBlazor/Services/TcpSocket/DefaultTcpSocketClient.cs @@ -45,13 +45,13 @@ public void SetDataHandler(IDataPackageHandler handler) _dataPackageHandler = handler; } - public Task ConnectAsync(string host, int port, CancellationToken token = default) + public ValueTask ConnectAsync(string host, int port, CancellationToken token = default) { var endPoint = new IPEndPoint(GetIPAddress(host), port); return ConnectAsync(endPoint, token); } - public async Task ConnectAsync(IPEndPoint endPoint, CancellationToken token = default) + public async ValueTask ConnectAsync(IPEndPoint endPoint, CancellationToken token = default) { var ret = false; try @@ -81,7 +81,7 @@ public async Task ConnectAsync(IPEndPoint endPoint, CancellationToken toke return ret; } - public async Task SendAsync(Memory data, CancellationToken token = default) + public async ValueTask SendAsync(ReadOnlyMemory data, CancellationToken token = default) { if (_client is not { Connected: true }) { @@ -110,7 +110,7 @@ public async Task SendAsync(Memory data, CancellationToken token = d return ret; } - private async Task ReceiveAsync() + private async ValueTask ReceiveAsync() { _receiveCancellationTokenSource ??= new(); while (_receiveCancellationTokenSource is { IsCancellationRequested: false }) diff --git a/src/BootstrapBlazor/Services/TcpSocket/ITcpSocketClient.cs b/src/BootstrapBlazor/Services/TcpSocket/ITcpSocketClient.cs index 3c89a34b1db..211203c2be5 100644 --- a/src/BootstrapBlazor/Services/TcpSocket/ITcpSocketClient.cs +++ b/src/BootstrapBlazor/Services/TcpSocket/ITcpSocketClient.cs @@ -45,7 +45,7 @@ public interface ITcpSocketClient : IDisposable /// langword="default"/> if not provided. /// A task that represents the asynchronous operation. The task result is if the connection /// is successfully established; otherwise, . - Task ConnectAsync(string host, int port, CancellationToken token = default); + ValueTask ConnectAsync(string host, int port, CancellationToken token = default); /// /// Establishes an asynchronous connection to the specified endpoint. @@ -57,7 +57,7 @@ public interface ITcpSocketClient : IDisposable /// langword="default"/> if not provided. /// A task that represents the asynchronous operation. The task result is if the connection /// is successfully established; otherwise, . - Task ConnectAsync(IPEndPoint endPoint, CancellationToken token = default); + ValueTask ConnectAsync(IPEndPoint endPoint, CancellationToken token = default); /// /// Sends the specified data asynchronously to the target endpoint. @@ -69,7 +69,7 @@ public interface ITcpSocketClient : IDisposable /// An optional to observe while waiting for the operation to complete. /// A task that represents the asynchronous operation. The task result is if the data was /// sent successfully; otherwise, . - Task SendAsync(Memory data, CancellationToken token = default); + ValueTask SendAsync(ReadOnlyMemory data, CancellationToken token = default); /// /// Closes the current connection or resource, releasing any associated resources. diff --git a/test/UnitTest/Services/TcpSocketFactoryTest.cs b/test/UnitTest/Services/TcpSocketFactoryTest.cs index 22b3d0f2e23..c3bdf59bb67 100644 --- a/test/UnitTest/Services/TcpSocketFactoryTest.cs +++ b/test/UnitTest/Services/TcpSocketFactoryTest.cs @@ -41,7 +41,6 @@ public void GetOrCreate_Ok() Assert.NotNull(client5); client5.Dispose(); - factory.Dispose(); } @@ -73,8 +72,8 @@ public async Task SendAsync_Error() var client = CreateClient(); // 测试未建立连接前调用 SendAsync 方法报异常逻辑 - var data = new Memory([1, 2, 3, 4, 5]); - var ex = await Assert.ThrowsAsync(() => client.SendAsync(data)); + var data = new ReadOnlyMemory([1, 2, 3, 4, 5]); + var ex = await Assert.ThrowsAsync(async () => await client.SendAsync(data)); Assert.Equal("TCP Socket is not connected 127.0.0.1:0", ex.Message); } @@ -95,7 +94,7 @@ public async Task SendAsync_Cancel() var cst = new CancellationTokenSource(); cst.Cancel(); - var data = new Memory([1, 2, 3, 4, 5]); + var data = new ReadOnlyMemory([1, 2, 3, 4, 5]); var result = await client.SendAsync(data, cst.Token); Assert.False(result); @@ -131,7 +130,7 @@ public async Task ReceiveAsync_Error() var methodInfo = client.GetType().GetMethod("ReceiveAsync", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); Assert.NotNull(methodInfo); - var task = (Task)methodInfo.Invoke(client, null)!; + var task = (ValueTask)methodInfo.Invoke(client, null)!; var ex = await Assert.ThrowsAsync(async () => await task); Assert.NotNull(ex); @@ -147,7 +146,7 @@ public async Task ReceiveAsync_Error() await client.ConnectAsync("localhost", port); // 发送数据导致接收数据异常 - var data = new Memory([1, 2, 3, 4, 5]); + var data = new ReadOnlyMemory([1, 2, 3, 4, 5]); await client.SendAsync(data); // 关闭连接 @@ -168,7 +167,7 @@ public async Task CloseByRemote_Ok() await client.ConnectAsync("localhost", port); // 发送数据 - await client.SendAsync(new Memory([1, 2, 3, 4, 5])); + await client.SendAsync(new ReadOnlyMemory([1, 2, 3, 4, 5])); // 关闭连接 StopTcpServer(server); @@ -187,7 +186,7 @@ public async Task FixLengthDataPackageHandler_Ok() Assert.True(client.IsConnected); var tcs = new TaskCompletionSource(); - Memory receivedBuffer = Memory.Empty; + ReadOnlyMemory receivedBuffer = ReadOnlyMemory.Empty; // 增加数据处理适配器 client.SetDataHandler(new FixLengthDataPackageHandler(7) @@ -196,12 +195,12 @@ public async Task FixLengthDataPackageHandler_Ok() { receivedBuffer = buffer; tcs.SetResult(); - return Task.CompletedTask; + return ValueTask.CompletedTask; } }); // 测试 SendAsync 方法 - var data = new Memory([1, 2, 3, 4, 5]); + var data = new ReadOnlyMemory([1, 2, 3, 4, 5]); var result = await client.SendAsync(data); Assert.True(result); @@ -227,7 +226,7 @@ public async Task FixLengthDataPackageHandler_Sticky() var connect = await client.ConnectAsync("localhost", port); var tcs = new TaskCompletionSource(); - Memory receivedBuffer = Memory.Empty; + ReadOnlyMemory receivedBuffer = ReadOnlyMemory.Empty; // 增加数据库处理适配器 client.SetDataHandler(new FixLengthDataPackageHandler(7) @@ -236,12 +235,12 @@ public async Task FixLengthDataPackageHandler_Sticky() { receivedBuffer = buffer; tcs.SetResult(); - return Task.CompletedTask; + return ValueTask.CompletedTask; } }); // 发送数据 - var data = new Memory([1, 2, 3, 4, 5]); + var data = new ReadOnlyMemory([1, 2, 3, 4, 5]); await client.SendAsync(data); // 等待接收数据处理完成 @@ -249,7 +248,7 @@ public async Task FixLengthDataPackageHandler_Sticky() // 验证接收到的数据 Assert.Equal(receivedBuffer.ToArray(), [1, 2, 3, 4, 5, 3, 4]); - receivedBuffer = Memory.Empty; + receivedBuffer = ReadOnlyMemory.Empty; tcs = new TaskCompletionSource(); // 等待第二次数据 @@ -282,7 +281,7 @@ public async Task DelimiterDataPackageHandler_Ok() var connect = await client.ConnectAsync("localhost", port); var tcs = new TaskCompletionSource(); - Memory receivedBuffer = Memory.Empty; + ReadOnlyMemory receivedBuffer = ReadOnlyMemory.Empty; // 增加数据库处理适配器 client.SetDataHandler(new DelimiterDataPackageHandler([0x13, 0x10]) @@ -291,12 +290,12 @@ public async Task DelimiterDataPackageHandler_Ok() { receivedBuffer = buffer; tcs.SetResult(); - return Task.CompletedTask; + return ValueTask.CompletedTask; } }); // 发送数据 - var data = new Memory([1, 2, 3, 4, 5]); + var data = new ReadOnlyMemory([1, 2, 3, 4, 5]); await client.SendAsync(data); // 等待接收数据处理完成 @@ -306,7 +305,7 @@ public async Task DelimiterDataPackageHandler_Ok() Assert.Equal(receivedBuffer.ToArray(), [1, 2, 3, 4, 5, 0x13, 0x10]); // 等待第二次数据 - receivedBuffer = Memory.Empty; + receivedBuffer = ReadOnlyMemory.Empty; tcs = new TaskCompletionSource(); await tcs.Task; @@ -355,7 +354,7 @@ private static async Task MockDelimiterPackageAsync(TcpClient client) } // 回写数据到客户端 - var block = new Memory(buffer, 0, len); + var block = new ReadOnlyMemory(buffer, 0, len); await stream.WriteAsync(block, CancellationToken.None); await Task.Delay(20); @@ -378,7 +377,7 @@ private static async Task MockSplitPackageAsync(TcpClient client) } // 回写数据到客户端 - var block = new Memory(buffer, 0, len); + var block = new ReadOnlyMemory(buffer, 0, len); await stream.WriteAsync(block, CancellationToken.None); // 模拟延时 @@ -402,7 +401,7 @@ private static async Task MockStickyPackageAsync(TcpClient client) } // 回写数据到客户端 - var block = new Memory(buffer, 0, len); + var block = new ReadOnlyMemory(buffer, 0, len); await stream.WriteAsync(block, CancellationToken.None); // 模拟延时 @@ -479,7 +478,7 @@ class MockSendErrorHandler : DataPackageHandlerBase { public ITcpSocketClient? Socket { get; set; } - public override async Task> SendAsync(Memory data) + public override async ValueTask> SendAsync(ReadOnlyMemory data) { Socket?.Close(); await Task.Delay(10); @@ -489,12 +488,12 @@ public override async Task> SendAsync(Memory data) class MockReceiveErrorHandler : DataPackageHandlerBase { - public override Task> SendAsync(Memory data) + public override ValueTask> SendAsync(ReadOnlyMemory data) { - return Task.FromResult(data); + return ValueTask.FromResult(data); } - public override async Task ReceiveAsync(Memory data) + public override async ValueTask ReceiveAsync(ReadOnlyMemory data) { await base.ReceiveAsync(data);