[fix]修正网络库SessionBase.SendMessageAsync被同步调用时阻塞UI上下文的问题,使用 await source.Task.ConfigureAwait(false)石头 authored at 2024-11-23 22:54:32
diff --git a/NewLife.Core/Caching/MemoryCache.cs b/NewLife.Core/Caching/MemoryCache.cs
index abf7f87..5c47eb6 100644
--- a/NewLife.Core/Caching/MemoryCache.cs
+++ b/NewLife.Core/Caching/MemoryCache.cs
@@ -991,7 +991,7 @@ public class MemoryQueue<T> : DisposeBase, IProducerConsumer<T>
{
if (timeout <= 0) return default;
- if (!await _occupiedNodes.WaitAsync(timeout * 1000)) return default;
+ if (!await _occupiedNodes.WaitAsync(timeout * 1000).ConfigureAwait(false)) return default;
}
return _collection.TryTake(out var item) ? item : default;
@@ -1007,7 +1007,7 @@ public class MemoryQueue<T> : DisposeBase, IProducerConsumer<T>
{
if (timeout <= 0) return default;
- if (!await _occupiedNodes.WaitAsync(timeout * 1000, cancellationToken)) return default;
+ if (!await _occupiedNodes.WaitAsync(timeout * 1000, cancellationToken).ConfigureAwait(false)) return default;
}
return _collection.TryTake(out var item) ? item : default;
diff --git a/NewLife.Core/Data/DbTable.cs b/NewLife.Core/Data/DbTable.cs
index e1474b3..43a24f1 100644
--- a/NewLife.Core/Data/DbTable.cs
+++ b/NewLife.Core/Data/DbTable.cs
@@ -525,8 +525,8 @@ public class DbTable : IEnumerable<DbRow>, ICloneable, IAccessor
};
using var writer = XmlWriter.Create(stream, set);
- await writer.WriteStartDocumentAsync();
- await writer.WriteStartElementAsync(null, "DbTable", null);
+ await writer.WriteStartDocumentAsync().ConfigureAwait(false);
+ await writer.WriteStartElementAsync(null, "DbTable", null).ConfigureAwait(false);
var cs = Columns ?? throw new ArgumentNullException(nameof(Columns));
var ts = Types ?? throw new ArgumentNullException(nameof(Types));
@@ -536,11 +536,11 @@ public class DbTable : IEnumerable<DbRow>, ICloneable, IAccessor
{
foreach (var row in rows)
{
- await writer.WriteStartElementAsync(null, "Table", null);
+ await writer.WriteStartElementAsync(null, "Table", null).ConfigureAwait(false);
for (var i = 0; i < cs.Length; i++)
{
//await writer.WriteElementStringAsync(null, Columns[i], null, row[i] + "");
- await writer.WriteStartElementAsync(null, cs[i], null);
+ await writer.WriteStartElementAsync(null, cs[i], null).ConfigureAwait(false);
//writer.WriteValue(row[i]);
if (ts[i] == typeof(Boolean))
@@ -550,18 +550,18 @@ public class DbTable : IEnumerable<DbRow>, ICloneable, IAccessor
else if (ts[i] == typeof(DateTimeOffset))
writer.WriteValue(row[i].ChangeType<DateTimeOffset>());
else if (row[i] is IFormattable ft)
- await writer.WriteStringAsync(ft + "");
+ await writer.WriteStringAsync(ft + "").ConfigureAwait(false);
else
- await writer.WriteStringAsync(row[i] + "");
+ await writer.WriteStringAsync(row[i] + "").ConfigureAwait(false);
- await writer.WriteEndElementAsync();
+ await writer.WriteEndElementAsync().ConfigureAwait(false);
}
- await writer.WriteEndElementAsync();
+ await writer.WriteEndElementAsync().ConfigureAwait(false);
}
}
- await writer.WriteEndElementAsync();
- await writer.WriteEndDocumentAsync();
+ await writer.WriteEndElementAsync().ConfigureAwait(false);
+ await writer.WriteEndDocumentAsync().ConfigureAwait(false);
}
#endregion
diff --git a/NewLife.Core/Data/IPacket.cs b/NewLife.Core/Data/IPacket.cs
index cbf3d47..4919ae7 100644
--- a/NewLife.Core/Data/IPacket.cs
+++ b/NewLife.Core/Data/IPacket.cs
@@ -180,12 +180,12 @@ public static class PacketHelper
for (var p = pk; p != null; p = p.Next)
{
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
- await stream.WriteAsync(p.GetMemory(), cancellationToken);
+ await stream.WriteAsync(p.GetMemory(), cancellationToken).ConfigureAwait(false);
#else
if (p is ArrayPacket ap)
- await stream.WriteAsync(ap.Buffer, ap.Offset, ap.Length, cancellationToken);
+ await stream.WriteAsync(ap.Buffer, ap.Offset, ap.Length, cancellationToken).ConfigureAwait(false);
else
- await stream.WriteAsync(p.GetMemory(), cancellationToken);
+ await stream.WriteAsync(p.GetMemory(), cancellationToken).ConfigureAwait(false);
#endif
}
}
diff --git a/NewLife.Core/Data/Packet.cs b/NewLife.Core/Data/Packet.cs
index 322a856..f6d01b8 100644
--- a/NewLife.Core/Data/Packet.cs
+++ b/NewLife.Core/Data/Packet.cs
@@ -425,8 +425,8 @@ public class Packet : IPacket
/// <returns></returns>
public async Task CopyToAsync(Stream stream)
{
- await stream.WriteAsync(Data, Offset, Count);
- if (Next != null) await Next.CopyToAsync(stream);
+ await stream.WriteAsync(Data, Offset, Count).ConfigureAwait(false);
+ if (Next != null) await Next.CopyToAsync(stream).ConfigureAwait(false);
}
/// <summary>异步复制到目标数据流</summary>
@@ -435,8 +435,8 @@ public class Packet : IPacket
/// <returns></returns>
public async Task CopyToAsync(Stream stream, CancellationToken cancellationToken)
{
- await stream.WriteAsync(Data, Offset, Count, cancellationToken);
- if (Next != null) await Next.CopyToAsync(stream, cancellationToken);
+ await stream.WriteAsync(Data, Offset, Count, cancellationToken).ConfigureAwait(false);
+ if (Next != null) await Next.CopyToAsync(stream, cancellationToken).ConfigureAwait(false);
}
/// <summary>深度克隆一份数据包,拷贝数据区</summary>
diff --git a/NewLife.Core/Http/HttpHelper.cs b/NewLife.Core/Http/HttpHelper.cs
index e98ada2..f5b98de 100644
--- a/NewLife.Core/Http/HttpHelper.cs
+++ b/NewLife.Core/Http/HttpHelper.cs
@@ -150,9 +150,9 @@ public static class HttpHelper
var addrs = NetUri.ParseAddress(ep.Host);
span?.AppendTag($"addrs={addrs?.Join()}");
if (addrs != null && addrs.Length > 0)
- await socket.ConnectAsync(addrs, ep.Port, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
+ await socket.ConnectAsync(addrs, ep.Port, cancellationToken).ConfigureAwait(false);
else
- await socket.ConnectAsync(ep, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
+ await socket.ConnectAsync(ep, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -529,14 +529,14 @@ public static class HttpHelper
{
if (filter != null) await filter.OnRequest(client, request, null, cancellationToken);
- var response = await client.SendAsync(request, cancellationToken);
+ var response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false);
if (filter != null) await filter.OnResponse(client, response, request, cancellationToken);
#if NET5_0_OR_GREATER
- var result = await response.Content.ReadAsStringAsync(cancellationToken);
+ var result = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
#else
- var result = await response.Content.ReadAsStringAsync();
+ var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
#endif
// 增加埋点数据
@@ -577,11 +577,11 @@ public static class HttpHelper
/// <param name="fileName">目标文件名</param>
public static async Task DownloadFileAsync(this HttpClient client, String requestUri, String fileName)
{
- var rs = await client.GetStreamAsync(requestUri);
+ var rs = await client.GetStreamAsync(requestUri).ConfigureAwait(false);
fileName.EnsureDirectory(true);
using var fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
- await rs.CopyToAsync(fs);
- await fs.FlushAsync();
+ await rs.CopyToAsync(fs).ConfigureAwait(false);
+ await fs.FlushAsync().ConfigureAwait(false);
}
/// <summary>下载文件</summary>
@@ -592,23 +592,23 @@ public static class HttpHelper
public static async Task DownloadFileAsync(this HttpClient client, String requestUri, String fileName, CancellationToken cancellationToken)
{
#if NET5_0_OR_GREATER
- var rs = await client.GetStreamAsync(requestUri, cancellationToken);
+ var rs = await client.GetStreamAsync(requestUri, cancellationToken).ConfigureAwait(false);
fileName.EnsureDirectory(true);
using var fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
- await rs.CopyToAsync(fs, cancellationToken);
- await fs.FlushAsync(cancellationToken);
+ await rs.CopyToAsync(fs, cancellationToken).ConfigureAwait(false);
+ await fs.FlushAsync(cancellationToken).ConfigureAwait(false);
#elif NETSTANDARD2_1_OR_GREATER || NETCOREAPP
- var rs = await client.GetStreamAsync(requestUri);
+ var rs = await client.GetStreamAsync(requestUri).ConfigureAwait(false);
fileName.EnsureDirectory(true);
using var fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
- await rs.CopyToAsync(fs, cancellationToken);
- await fs.FlushAsync(cancellationToken);
+ await rs.CopyToAsync(fs, cancellationToken).ConfigureAwait(false);
+ await fs.FlushAsync(cancellationToken).ConfigureAwait(false);
#else
- var rs = await client.GetStreamAsync(requestUri);
+ var rs = await client.GetStreamAsync(requestUri).ConfigureAwait(false);
fileName.EnsureDirectory(true);
using var fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
- await rs.CopyToAsync(fs, 81920, cancellationToken);
- await fs.FlushAsync(cancellationToken);
+ await rs.CopyToAsync(fs, 81920, cancellationToken).ConfigureAwait(false);
+ await fs.FlushAsync(cancellationToken).ConfigureAwait(false);
#endif
}
@@ -711,7 +711,7 @@ public static class HttpHelper
var buf = onProcess != null ? onProcess(msg) : msg.GetBytes();
if (buf != null && buf.Length > 0)
- await socket.SendAsync(new ArraySegment<Byte>(buf), System.Net.WebSockets.WebSocketMessageType.Text, true, token);
+ await socket.SendAsync(new ArraySegment<Byte>(buf), System.Net.WebSockets.WebSocketMessageType.Text, true, token).ConfigureAwait(false);
}
else
{
@@ -750,7 +750,7 @@ public static class HttpHelper
var buf = new Byte[4 * 1024];
while (!source.IsCancellationRequested && socket.State == WebSocketState.Open)
{
- var data = await socket.ReceiveAsync(new ArraySegment<Byte>(buf), source.Token);
+ var data = await socket.ReceiveAsync(new ArraySegment<Byte>(buf), source.Token).ConfigureAwait(false);
if (data.MessageType == System.Net.WebSockets.WebSocketMessageType.Close) break;
if (data.MessageType == System.Net.WebSockets.WebSocketMessageType.Text)
{
@@ -763,7 +763,7 @@ public static class HttpHelper
if (!source.IsCancellationRequested) source.Cancel();
if (socket.State == WebSocketState.Open)
- await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "finish", default);
+ await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "finish", default).ConfigureAwait(false);
}
catch (TaskCanceledException) { }
catch (OperationCanceledException) { }
diff --git a/NewLife.Core/Http/TinyHttpClient.cs b/NewLife.Core/Http/TinyHttpClient.cs
index 30383a0..278aa26 100644
--- a/NewLife.Core/Http/TinyHttpClient.cs
+++ b/NewLife.Core/Http/TinyHttpClient.cs
@@ -202,7 +202,7 @@ public class TinyHttpClient : DisposeBase
{
// 使用内存流拼接需要多次接收的数据包,降低逻辑复杂度
var ms = new MemoryStream(res.ContentLength);
- await rs.CopyToAsync(ms);
+ await rs.CopyToAsync(ms).ConfigureAwait(false);
var total = rs.Length;
while (total < res.ContentLength)
diff --git a/NewLife.Core/IO/CsvFile.cs b/NewLife.Core/IO/CsvFile.cs
index 10d42cf..4f93edf 100644
--- a/NewLife.Core/IO/CsvFile.cs
+++ b/NewLife.Core/IO/CsvFile.cs
@@ -89,15 +89,15 @@ public class CsvFile : IDisposable
_disposed = true;
// 必须刷新写入器,否则可能丢失一截数据
- if (_writer != null) await _writer.FlushAsync();
+ if (_writer != null) await _writer.FlushAsync().ConfigureAwait(false);
if (!_leaveOpen && _stream != null)
{
_reader.TryDispose();
- if (_writer != null) await _writer.DisposeAsync();
+ if (_writer != null) await _writer.DisposeAsync().ConfigureAwait(false);
- await _stream.DisposeAsync();
+ await _stream.DisposeAsync().ConfigureAwait(false);
}
GC.SuppressFinalize(this);
@@ -210,7 +210,7 @@ public class CsvFile : IDisposable
var str = BuildLine(line);
- await _writer.WriteLineAsync(str);
+ await _writer.WriteLineAsync(str).ConfigureAwait(false);
}
/// <summary>构建一行</summary>
diff --git a/NewLife.Core/Net/NetServer.cs b/NewLife.Core/Net/NetServer.cs
index 67637e3..5e42694 100644
--- a/NewLife.Core/Net/NetServer.cs
+++ b/NewLife.Core/Net/NetServer.cs
@@ -552,7 +552,7 @@ public class NetServer : DisposeBase, IServer, IExtend, ILogFeature
ts.Add(Task.Run(() => item.Value.Send(data)));
}
- await Task.WhenAll(ts);
+ await Task.WhenAll(ts).ConfigureAwait(false);
return Sessions.Count;
}
@@ -572,7 +572,7 @@ public class NetServer : DisposeBase, IServer, IExtend, ILogFeature
ts.Add(Task.Run(() => item.Value.Send(data)));
}
- await Task.WhenAll(ts);
+ await Task.WhenAll(ts).ConfigureAwait(false);
return Sessions.Count;
}
diff --git a/NewLife.Core/Net/SessionBase.cs b/NewLife.Core/Net/SessionBase.cs
index 65a9823..b0c4f96 100644
--- a/NewLife.Core/Net/SessionBase.cs
+++ b/NewLife.Core/Net/SessionBase.cs
@@ -366,9 +366,9 @@ public abstract class SessionBase : DisposeBase, ISocketClient, ITransport, ILog
var ar = Client.BeginReceive(pk.Buffer, 0, pk.Length, SocketFlags.None, null, Client);
var size = ar.IsCompleted ?
Client.EndReceive(ar) :
- await Task.Factory.FromAsync(ar, Client.EndReceive);
+ await Task.Factory.FromAsync(ar, Client.EndReceive).ConfigureAwait(false);
#else
- var size = await Client.ReceiveAsync(pk.GetMemory(), SocketFlags.None, cancellationToken);
+ var size = await Client.ReceiveAsync(pk.GetMemory(), SocketFlags.None, cancellationToken).ConfigureAwait(false);
#endif
if (span != null) span.Value = size;
@@ -729,7 +729,7 @@ public abstract class SessionBase : DisposeBase, ISocketClient, ITransport, ILog
var rs = (Int32)(Pipeline.Write(ctx, message) ?? 0);
if (rs < 0) return TaskEx.CompletedTask;
- return await source.Task;
+ return await source.Task.ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -769,7 +769,7 @@ public abstract class SessionBase : DisposeBase, ISocketClient, ITransport, ILog
// https://stackoverflow.com/questions/14627226/why-is-my-async-await-with-cancellationtokensource-leaking-memory
using (cancellationToken.Register(TrySetCanceled, source))
{
- return await source.Task;
+ return await source.Task.ConfigureAwait(false);
}
}
catch (Exception ex)
diff --git a/NewLife.Core/Net/TcpSession.cs b/NewLife.Core/Net/TcpSession.cs
index 7cf6100..03fe803 100644
--- a/NewLife.Core/Net/TcpSession.cs
+++ b/NewLife.Core/Net/TcpSession.cs
@@ -523,7 +523,7 @@ public class TcpSession : SessionBase, ISocketSession
try
{
var pk = new OwnerPacket(BufferSize);
- var size = await ss.ReadAsync(pk.Buffer, 0, pk.Length, cancellationToken);
+ var size = await ss.ReadAsync(pk.Buffer, 0, pk.Length, cancellationToken).ConfigureAwait(false);
if (span != null) span.Value = size;
return pk.Resize(size);
diff --git a/NewLife.Core/Net/UdpSession.cs b/NewLife.Core/Net/UdpSession.cs
index 8b42aa8..8983a54 100644
--- a/NewLife.Core/Net/UdpSession.cs
+++ b/NewLife.Core/Net/UdpSession.cs
@@ -220,7 +220,7 @@ public class UdpSession : DisposeBase, ISocketSession, ITransport, ILogFeature
var rs = (Int32)(Pipeline.Write(ctx, message) ?? -1);
if (rs < 0) return TaskEx.CompletedTask;
- return await source.Task;
+ return await source.Task.ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -259,7 +259,7 @@ public class UdpSession : DisposeBase, ISocketSession, ITransport, ILogFeature
// 注册取消时的处理,如果没有收到响应,取消发送等待
using (cancellationToken.Register(TrySetCanceled, source))
{
- return await source.Task;
+ return await source.Task.ConfigureAwait(false);
}
}
catch (Exception ex)
@@ -321,12 +321,12 @@ public class UdpSession : DisposeBase, ISocketSession, ITransport, ILogFeature
var ar = socket.BeginReceiveFrom(pk.Buffer, 0, pk.Length, SocketFlags.None, ref ep, null, socket);
var size = ar.IsCompleted ?
socket.EndReceive(ar) :
- await Task.Factory.FromAsync(ar, e => socket.EndReceiveFrom(e, ref ep));
+ await Task.Factory.FromAsync(ar, e => socket.EndReceiveFrom(e, ref ep)).ConfigureAwait(false);
#elif NET7_0_OR_GREATER
- var result = await socket.ReceiveFromAsync(pk.GetMemory(), ep, cancellationToken);
+ var result = await socket.ReceiveFromAsync(pk.GetMemory(), ep, cancellationToken).ConfigureAwait(false);
var size = result.ReceivedBytes;
#else
- var result = await socket.ReceiveFromAsync(pk.Buffer, SocketFlags.None, ep);
+ var result = await socket.ReceiveFromAsync(pk.Buffer, SocketFlags.None, ep).ConfigureAwait(false);
var size = result.ReceivedBytes;
#endif
if (span != null) span.Value = size;
diff --git a/NewLife.Core/Remoting/ApiHelper.cs b/NewLife.Core/Remoting/ApiHelper.cs
index 8e30943..14b82a0 100644
--- a/NewLife.Core/Remoting/ApiHelper.cs
+++ b/NewLife.Core/Remoting/ApiHelper.cs
@@ -107,7 +107,7 @@ public static class ApiHelper
// 发起请求
if (filter != null) await filter.OnRequest(client, request, null, cancellationToken);
- var response = await client.SendAsync(request, cancellationToken);
+ var response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false);
if (filter != null) await filter.OnResponse(client, response, request, cancellationToken);
@@ -241,7 +241,7 @@ public static class ApiHelper
var rtype = typeof(TResult);
if (rtype == typeof(HttpResponseMessage)) return (TResult)(Object)response;
- var buf = response.Content == null ? null : (await response.Content.ReadAsByteArrayAsync());
+ var buf = response.Content == null ? null : (await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false));
// 异常处理
if (response.StatusCode >= HttpStatusCode.BadRequest)
diff --git a/NewLife.Core/Remoting/ApiHttpClient.cs b/NewLife.Core/Remoting/ApiHttpClient.cs
index 2a46d30..b00cff4 100644
--- a/NewLife.Core/Remoting/ApiHttpClient.cs
+++ b/NewLife.Core/Remoting/ApiHttpClient.cs
@@ -499,7 +499,7 @@ public class ApiHttpClient : DisposeBase, IApiClient, IConfigMapping, ILogFeatur
var filter = Filter;
if (filter != null) await filter.OnRequest(client, request, this, cancellationToken);
- var response = await client.SendAsync(request, cancellationToken);
+ var response = await client.SendAsync(request, cancellationToken).ConfigureAwait(false);
if (filter != null) await filter.OnResponse(client, response, this, cancellationToken);
diff --git a/NewLife.Core/Web/WebClientX.cs b/NewLife.Core/Web/WebClientX.cs
index 1d96252..93a6e25 100644
--- a/NewLife.Core/Web/WebClientX.cs
+++ b/NewLife.Core/Web/WebClientX.cs
@@ -103,7 +103,7 @@ public class WebClientX : DisposeBase
//var task = content != null ? http.PostAsync(address, content) : http.GetAsync(address);
//var rs = await task;
using var ctx = CancellationTokenSource.CreateLinkedTokenSource(new CancellationTokenSource(Timeout).Token, cancellationToken);
- var rs = await http.SendAsync(request, ctx.Token);
+ var rs = await http.SendAsync(request, ctx.Token).ConfigureAwait(false);
if (rs.StatusCode < HttpStatusCode.BadRequest)
{
@@ -171,7 +171,7 @@ public class WebClientX : DisposeBase
address = CheckAuth(address);
var rs = await SendAsync(address, null, cancellationToken);
- return await rs.ReadAsStringAsync();
+ return await rs.ReadAsStringAsync().ConfigureAwait(false);
}
/// <summary>下载文件</summary>
@@ -185,9 +185,9 @@ public class WebClientX : DisposeBase
var rs = await SendAsync(address, null, cancellationToken);
fileName.EnsureDirectory(true);
using var fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
- await rs.CopyToAsync(fs);
+ await rs.CopyToAsync(fs).ConfigureAwait(false);
fs.SetLength(fs.Position);
- await fs.FlushAsync();
+ await fs.FlushAsync().ConfigureAwait(false);
}
#endregion
diff --git a/NewLife.Core/Yun/OssClient.cs b/NewLife.Core/Yun/OssClient.cs
index ba09068..d1b7c06 100644
--- a/NewLife.Core/Yun/OssClient.cs
+++ b/NewLife.Core/Yun/OssClient.cs
@@ -106,7 +106,7 @@ public class OssClient : IObjectStorage
request.Headers.Authorization = new AuthenticationHeaderValue("OSS", AppId + ":" + signature);
var http = GetClient();
- var rs = await http.SendAsync(request);
+ var rs = await http.SendAsync(request).ConfigureAwait(false);
return await ApiHelper.ProcessResponse<TResult>(rs);
}