精确控制内存释放

This commit is contained in:
智能大石头 2025-03-11 13:55:30 +08:00
parent 40f7560753
commit f5bb807a37
5 changed files with 62 additions and 19 deletions

View File

@ -112,7 +112,13 @@ public class RedisQueue<T> : QueueBase, IProducerConsumer<T>
if (timeout > 0 && Redis.Timeout < (timeout + 1) * 1000) Redis.Timeout = (timeout + 1) * 1000; if (timeout > 0 && Redis.Timeout < (timeout + 1) * 1000) Redis.Timeout = (timeout + 1) * 1000;
var rs = Execute((rc, k) => rc.Execute<IPacket[]>("BRPOP", Key, timeout), true); var rs = Execute((rc, k) => rc.Execute<IPacket[]>("BRPOP", Key, timeout), true);
return rs == null || rs.Length < 2 ? default : (T?)Redis.Encoder.Decode(rs[1], typeof(T)); if (rs == null || rs.Length < 2) return default;
var msg = (T?)Redis.Encoder.Decode(rs[1], typeof(T));
if (typeof(T) != typeof(IPacket)) rs.TryDispose();
return msg;
} }
/// <summary>异步消费获取</summary> /// <summary>异步消费获取</summary>
@ -126,7 +132,13 @@ public class RedisQueue<T> : QueueBase, IProducerConsumer<T>
if (timeout > 0 && Redis.Timeout < (timeout + 1) * 1000) Redis.Timeout = (timeout + 1) * 1000; if (timeout > 0 && Redis.Timeout < (timeout + 1) * 1000) Redis.Timeout = (timeout + 1) * 1000;
var rs = await ExecuteAsync((rc, k) => rc.ExecuteAsync<IPacket[]>("BRPOP", [Key, timeout], cancellationToken), true).ConfigureAwait(false); var rs = await ExecuteAsync((rc, k) => rc.ExecuteAsync<IPacket[]>("BRPOP", [Key, timeout], cancellationToken), true).ConfigureAwait(false);
return rs == null || rs.Length < 2 ? default : (T?)Redis.Encoder.Decode(rs[1], typeof(T)); if (rs == null || rs.Length < 2) return default;
var msg = (T?)Redis.Encoder.Decode(rs[1], typeof(T));
if (typeof(T) != typeof(IPacket)) rs.TryDispose();
return msg;
} }
/// <summary>异步消费获取</summary> /// <summary>异步消费获取</summary>

View File

@ -678,20 +678,22 @@ public class RedisClient : DisposeBase
try try
{ {
// 管道模式 // 管道模式
var type = typeof(TResult);
if (_ps != null) if (_ps != null)
{ {
_ps.Add(new Command(cmd, args, typeof(TResult))); _ps.Add(new Command(cmd, args, type));
return default; return default;
} }
var rs = ExecuteCommand(cmd, args); var rs = ExecuteCommand(cmd, args);
if (rs == null) return default; if (rs == null) return default;
if (rs is TResult rs2) return rs2; if (rs is TResult rs2) return rs2;
if (TryChangeType(rs, typeof(TResult), out var target))
if (TryChangeType(rs, type, out var target))
{ {
//!!! 外部调用者可能需要直接使用内部申请的OwnerPacket所以这里不释放 //!!! 外部调用者可能需要直接使用内部申请的OwnerPacket所以这里不释放
//// 释放内部申请的OwnerPacket // 释放内部申请的OwnerPacket
//rs.TryDispose(); if (type != typeof(IPacket) && type != typeof(IPacket[])) rs.TryDispose();
return (TResult?)target; return (TResult?)target;
} }
@ -725,11 +727,13 @@ public class RedisClient : DisposeBase
value = default; value = default;
if (rs == null) return false; if (rs == null) return false;
if (TryChangeType(rs, typeof(TResult), out var target))
var type = typeof(TResult);
if (TryChangeType(rs, type, out var target))
{ {
//!!! 外部调用者可能需要直接使用内部申请的OwnerPacket所以这里不释放 //!!! 外部调用者可能需要直接使用内部申请的OwnerPacket所以这里不释放
//// 释放内部申请的OwnerPacket // 释放内部申请的OwnerPacket
//rs.TryDispose(); if (type != typeof(IPacket) && type != typeof(IPacket[])) rs.TryDispose();
value = (TResult?)target; value = (TResult?)target;
return true; return true;
} }
@ -778,20 +782,22 @@ public class RedisClient : DisposeBase
public virtual async Task<TResult?> ExecuteAsync<TResult>(String cmd, Object?[] args, CancellationToken cancellationToken) public virtual async Task<TResult?> ExecuteAsync<TResult>(String cmd, Object?[] args, CancellationToken cancellationToken)
{ {
// 管道模式 // 管道模式
var type = typeof(TResult);
if (_ps != null) if (_ps != null)
{ {
_ps.Add(new Command(cmd, args, typeof(TResult))); _ps.Add(new Command(cmd, args, type));
return default; return default;
} }
var rs = await ExecuteAsync(cmd, args, cancellationToken).ConfigureAwait(false); var rs = await ExecuteAsync(cmd, args, cancellationToken).ConfigureAwait(false);
if (rs == null) return default; if (rs == null) return default;
if (rs is TResult rs2) return rs2; if (rs is TResult rs2) return rs2;
if (TryChangeType(rs, typeof(TResult), out var target))
if (TryChangeType(rs, type, out var target))
{ {
//!!! 外部调用者可能需要直接使用内部申请的OwnerPacket所以这里不释放 //!!! 外部调用者可能需要直接使用内部申请的OwnerPacket所以这里不释放
//// 释放内部申请的OwnerPacket // 释放内部申请的OwnerPacket
//rs.TryDispose(); if (type != typeof(IPacket) && type != typeof(IPacket[])) rs.TryDispose();
return (TResult?)target; return (TResult?)target;
} }
@ -812,7 +818,14 @@ public class RedisClient : DisposeBase
//var rs = ExecuteCommand(null, null, null); //var rs = ExecuteCommand(null, null, null);
if (rs == null) return default; if (rs == null) return default;
if (rs is TResult rs2) return rs2; if (rs is TResult rs2) return rs2;
if (TryChangeType(rs, typeof(TResult), out var target)) return (TResult?)target;
var type = typeof(TResult);
if (TryChangeType(rs, type, out var target))
{
// 释放内部申请的OwnerPacket
if (type != typeof(IPacket) && type != typeof(IPacket[])) rs.TryDispose();
return (TResult?)target;
}
return default; return default;
} }
@ -942,8 +955,8 @@ public class RedisClient : DisposeBase
if (rs != null && TryChangeType(rs, ps[i].Type, out var target) && target != null) if (rs != null && TryChangeType(rs, ps[i].Type, out var target) && target != null)
{ {
//!!! 外部调用者可能需要直接使用内部申请的OwnerPacket所以这里不释放 //!!! 外部调用者可能需要直接使用内部申请的OwnerPacket所以这里不释放
//// 释放内部申请的OwnerPacket // 释放内部申请的OwnerPacket
//rs.TryDispose(); if (ps[i].Type != typeof(IPacket) && ps[i].Type != typeof(IPacket[])) rs.TryDispose();
list[i] = target; list[i] = target;
} }
} }

View File

@ -68,6 +68,8 @@ public class RedisHash<TKey, TValue> : RedisBase, IDictionary<TKey, TValue>
value = Redis.Encoder.Decode<TValue>(pk)!; value = Redis.Encoder.Decode<TValue>(pk)!;
//value = (TValue?)Redis.Encoder.Decode(pk, typeof(TValue))!; //value = (TValue?)Redis.Encoder.Decode(pk, typeof(TValue))!;
if (typeof(TValue) != typeof(IPacket)) pk.TryDispose();
return true; return true;
} }
@ -164,6 +166,8 @@ public class RedisHash<TKey, TValue> : RedisBase, IDictionary<TKey, TValue>
dic[key] = value; dic[key] = value;
} }
if (typeof(TKey) != typeof(IPacket) && typeof(TValue) != typeof(IPacket)) rs.TryDispose();
return dic; return dic;
} }

View File

@ -83,7 +83,13 @@ public class RedisStack<T> : RedisBase, IProducerConsumer<T>
if (timeout < 0) return Execute((rc, k) => rc.Execute<T>("RPOP", Key), true); if (timeout < 0) return Execute((rc, k) => rc.Execute<T>("RPOP", Key), true);
var rs = Execute((rc, k) => rc.Execute<IPacket[]>("BRPOP", Key, timeout), true); var rs = Execute((rc, k) => rc.Execute<IPacket[]>("BRPOP", Key, timeout), true);
return rs == null || rs.Length < 2 ? default : (T?)Redis.Encoder.Decode(rs[1], typeof(T)); if (rs == null || rs.Length < 2) return default;
var msg = (T?)Redis.Encoder.Decode(rs[1], typeof(T));
if (typeof(T) != typeof(IPacket)) rs.TryDispose();
return msg;
} }
/// <summary>异步消费获取</summary> /// <summary>异步消费获取</summary>
@ -95,7 +101,13 @@ public class RedisStack<T> : RedisBase, IProducerConsumer<T>
if (timeout < 0) return await ExecuteAsync((rc, k) => rc.ExecuteAsync<T>("RPOP", Key), true).ConfigureAwait(false); if (timeout < 0) return await ExecuteAsync((rc, k) => rc.ExecuteAsync<T>("RPOP", Key), true).ConfigureAwait(false);
var rs = await ExecuteAsync((rc, k) => rc.ExecuteAsync<IPacket[]>("BRPOP", [Key, timeout], cancellationToken), true).ConfigureAwait(false); var rs = await ExecuteAsync((rc, k) => rc.ExecuteAsync<IPacket[]>("BRPOP", [Key, timeout], cancellationToken), true).ConfigureAwait(false);
return rs == null || rs.Length < 2 ? default : (T?)Redis.Encoder.Decode(rs[1], typeof(T)); if (rs == null || rs.Length < 2) return default;
var msg = (T?)Redis.Encoder.Decode(rs[1], typeof(T));
if (typeof(T) != typeof(IPacket)) rs.TryDispose();
return msg;
} }
/// <summary>异步消费获取</summary> /// <summary>异步消费获取</summary>

View File

@ -90,7 +90,7 @@ public class RedisStat : DisposeBase
if (!_redis.Rename(key, newKey, false)) return; if (!_redis.Rename(key, newKey, false)) return;
_redis.Remove($"exists:{key}"); _redis.Remove($"exists:{key}");
var rs = _redis.Execute(newKey, (r,k) => r.Execute<IPacket[]>("HGETALL", k)); var rs = _redis.Execute(newKey, (r, k) => r.Execute<IPacket[]>("HGETALL", k));
if (rs != null) if (rs != null)
{ {
var dic = new Dictionary<String, Int32>(); var dic = new Dictionary<String, Int32>();
@ -104,6 +104,8 @@ public class RedisStat : DisposeBase
OnSave(key, dic); OnSave(key, dic);
} }
rs.TryDispose();
_redis.Remove(newKey); _redis.Remove(newKey);
} }
#endregion #endregion