Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

修正内存泄露 #197

Merged
merged 2 commits into from
May 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Example/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ static void Main(string[] args)
connection.Open();
Console.WriteLine("ServerVersion:{0}", connection.ServerVersion);
Console.WriteLine("create {0} {1}", database, connection.CreateCommand($"create database {database};").ExecuteNonQuery());
Console.WriteLine("create table t {0} {1}", database, connection.CreateCommand($"create table {database}.t (ts timestamp, cdata int);").ExecuteNonQuery());
Console.WriteLine("create table t {0} {1}", database, connection.CreateCommand($"create table {database}.t (ts timestamp, cdata binary(255));").ExecuteNonQuery());
Console.WriteLine("insert into t values {0} ", connection.CreateCommand($"insert into {database}.t values ({(long)(DateTime.Now.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds)}, 10);").ExecuteNonQuery());
var pmcmd = connection.CreateCommand($"insert into {database}.t values (@ts, @v);");
Thread.Sleep(TimeSpan.FromSeconds(1));
pmcmd.Parameters.AddWithValue("@ts", DateTime.Now);//(long)(DateTime.Now.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds));
pmcmd.Parameters.AddWithValue("@v",1111);
pmcmd.Parameters.AddWithValue("@v","1111");
pmcmd.ExecuteNonQuery();
Console.WriteLine("单表插入一行数据 {0} ", connection.CreateCommand($"insert into {database}.t values ({(long)(DateTime.Now.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds)}, 10);").ExecuteNonQuery());
Thread.Sleep(100);
Expand Down
2 changes: 2 additions & 0 deletions src/IoTSharp.Data.Taos/Driver/TDengineDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ public struct TAOS_BIND
public IntPtr error;
public Int64 u;
public uint allocated;
public bool is_string;
}


Expand All @@ -163,6 +164,7 @@ public struct TAOS_MULTI_BIND

// line number, or the values number in buffer
public int num;
public bool is_string;
}

/// <summary>
Expand Down
9 changes: 7 additions & 2 deletions src/IoTSharp.Data.Taos/Driver/TaosBind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ public static TAOS_BIND BindBinary(String val)

TAOS_BIND bind = new TAOS_BIND();
// IntPtr unmanagedBinary = Marshal.StringToHGlobalAnsi(val);
IntPtr c_str = Marshal.StringToCoTaskMemUTF8 (val);
IntPtr c_str = Marshal.StringToCoTaskMemUTF8(val);

var strToBytes = System.Text.Encoding.UTF8.GetBytes(val);
int length = strToBytes.Length;
Expand All @@ -260,6 +260,7 @@ public static TAOS_BIND BindBinary(String val)
bind.buffer_length = length;
bind.length = lenPtr;
bind.is_null = IntPtr.Zero;
bind.is_string = true;

return bind;
}
Expand All @@ -280,6 +281,7 @@ public static TAOS_BIND BindNchar(String val)
bind.buffer_length = length;
bind.length = lenPtr;
bind.is_null = IntPtr.Zero;
bind.is_string = true;

return bind;
}
Expand Down Expand Up @@ -322,7 +324,10 @@ public static void FreeTaosBind(TAOS_BIND[] binds)
{
foreach (TAOS_BIND bind in binds)
{
Marshal.FreeHGlobal(bind.buffer);
if (bind.is_string)
Marshal.FreeCoTaskMem(bind.buffer);
else
Marshal.FreeHGlobal(bind.buffer);
Marshal.FreeHGlobal(bind.length);
if (bind.is_null != IntPtr.Zero)
{
Expand Down
7 changes: 6 additions & 1 deletion src/IoTSharp.Data.Taos/Driver/TaosMultiBind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ public static TAOS_MULTI_BIND MultiBindBinary(string[] arr)
multiBind.length = lengthArr;
multiBind.is_null = nullArr;
multiBind.num = elementCount;
multiBind.is_string = true;

return multiBind;
}
Expand Down Expand Up @@ -530,6 +531,7 @@ public static TAOS_MULTI_BIND MultiBindNchar(string[] arr)
multiBind.length = lengthArr;
multiBind.is_null = nullArr;
multiBind.num = elementCount;
multiBind.is_string = true;

return multiBind;
}
Expand Down Expand Up @@ -573,7 +575,10 @@ public static void FreeTaosBind(TAOS_MULTI_BIND[] mBinds)
{
foreach (TAOS_MULTI_BIND bind in mBinds)
{
Marshal.FreeHGlobal(bind.buffer);
if (bind.is_string)
Marshal.FreeCoTaskMem(bind.buffer);
else
Marshal.FreeHGlobal(bind.buffer);
Marshal.FreeHGlobal(bind.length);
Marshal.FreeHGlobal(bind.is_null);
}
Expand Down
45 changes: 23 additions & 22 deletions src/IoTSharp.Data.Taos/TaosCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -329,17 +329,18 @@ public new virtual TaosDataReader ExecuteReader(CommandBehavior behavior)
int _affectRows = 0;
Task<IntPtr> code = null;
bool isok = false;
TAOS_BIND[] binds = null;
if (_parameters.IsValueCreated)
{
var stmt = TDengine.StmtInit(_taos);
if (stmt != IntPtr.Zero)
{
var pms = _parameters.Value;
List<TAOS_BIND> binds = BindParamters(pms);
binds = BindParamters(pms);
int res = TDengine.StmtPrepare(stmt, _commandText);
if (res == 0)
{
int ret = TDengine.StmtBindParam(stmt, binds.ToArray());
int ret = TDengine.StmtBindParam(stmt, binds);
if (ret == 0)
{
if (TDengine.StmtIsInsert(stmt))
Expand All @@ -358,7 +359,7 @@ public new virtual TaosDataReader ExecuteReader(CommandBehavior behavior)
else
{
string error = TDengine.StmtErrorStr(stmt);
TaosBind.FreeTaosBind(binds.ToArray());
TaosBind.FreeTaosBind(binds);
TDengine.StmtClose(stmt);
TaosException.ThrowExceptionForRC(-10010, $"stmt execute failed,{ TDengine.StmtErrorStr(stmt)}", null);
}
Expand All @@ -369,7 +370,7 @@ public new virtual TaosDataReader ExecuteReader(CommandBehavior behavior)
if (isok == false)
{
string error = TDengine.StmtErrorStr(stmt);
TaosBind.FreeTaosBind(binds.ToArray());
TaosBind.FreeTaosBind(binds);
TDengine.StmtClose(stmt);
TaosException.ThrowExceptionForRC(-10009, $"stmt execute timeout.", null);
}
Expand All @@ -378,7 +379,7 @@ public new virtual TaosDataReader ExecuteReader(CommandBehavior behavior)
{
string error = TDengine.StmtErrorStr(stmt);
TDengine.StmtClose(stmt);
TaosBind.FreeTaosBind(binds.ToArray());
TaosBind.FreeTaosBind(binds);
TaosException.ThrowExceptionForRC(-10008, $"stmt prepare failed,{ TDengine.StmtErrorStr(stmt)}", null);
}

Expand Down Expand Up @@ -411,7 +412,7 @@ public new virtual TaosDataReader ExecuteReader(CommandBehavior behavior)
Debug.WriteLine("index:" + j + ", type:" + meta.type + ", typename:" + meta.TypeName() + ", name:" + meta.name + ", size:" + meta.size);
#endif
}
dataReader = new TaosDataReader(this, metas, closeConnection, code.Result, _affectRows, metas.Count);
dataReader = new TaosDataReader(this, metas, closeConnection, code.Result, _affectRows, metas.Count, binds);
}
else if (isok && TDengine.ErrorNo(code.Result) != 0)
{
Expand Down Expand Up @@ -445,9 +446,9 @@ public new virtual TaosDataReader ExecuteReader(CommandBehavior behavior)
return dataReader;
}

private List<TAOS_BIND> BindParamters(TaosParameterCollection pms)
private TAOS_BIND[] BindParamters(TaosParameterCollection pms)
{
List<TAOS_BIND> binds = new List<TAOS_BIND>();
TAOS_BIND[] binds = new TAOS_BIND[pms.Count];
for (int i = 0; i < pms.Count; i++)
{

Expand All @@ -456,54 +457,54 @@ private List<TAOS_BIND> BindParamters(TaosParameterCollection pms)
switch (TypeInfo.GetTypeCode(tp.Value?.GetType()))
{
case TypeCode.Boolean:
binds.Add(TaosBind.BindBool((tp.Value as bool?).GetValueOrDefault()));
binds[i] = TaosBind.BindBool((tp.Value as bool?).GetValueOrDefault());
break;
case TypeCode.Char:
binds.Add(TaosBind.BindNchar(tp.Value as string));
binds[i] = TaosBind.BindNchar(tp.Value as string);
break;
case TypeCode.Byte:
case TypeCode.SByte:
binds.Add(TaosBind.BindUTinyInt((tp.Value as byte?).GetValueOrDefault()));
binds[i] = TaosBind.BindUTinyInt((tp.Value as byte?).GetValueOrDefault());
break;
case TypeCode.DateTime:
var t0 = tp.Value as DateTime?;
if (!t0.HasValue)
{
throw new ArgumentException($"InvalidArgumentOfDateTime{tp.Value}");
}
binds.Add(TaosBind.BindTimestamp(GetDateTimeFrom(t0.GetValueOrDefault(), _taos)));
binds[i] = TaosBind.BindTimestamp(GetDateTimeFrom(t0.GetValueOrDefault(), _taos));
break;
case TypeCode.DBNull:
binds.Add(TaosBind.BindNil());
binds[i] = TaosBind.BindNil();
break;
case TypeCode.Single:
binds.Add(TaosBind.BindFloat((tp.Value as float?).GetValueOrDefault()));
binds[i] = TaosBind.BindFloat((tp.Value as float?).GetValueOrDefault());
break;
case TypeCode.Decimal:
case TypeCode.Double:
binds.Add(TaosBind.BindDouble((tp.Value as double?).GetValueOrDefault()));
binds[i] = TaosBind.BindDouble((tp.Value as double?).GetValueOrDefault());
break;
case TypeCode.Int16:
binds.Add(TaosBind.BindSmallInt((tp.Value as short?).GetValueOrDefault()));
binds[i] = TaosBind.BindSmallInt((tp.Value as short?).GetValueOrDefault());
break;
case TypeCode.Int32:
binds.Add(TaosBind.BindInt((tp.Value as int?).GetValueOrDefault()));
binds[i] = TaosBind.BindInt((tp.Value as int?).GetValueOrDefault());
break;
case TypeCode.Int64:
binds.Add(TaosBind.BindBigInt((tp.Value as long?).GetValueOrDefault()));
binds[i] = TaosBind.BindBigInt((tp.Value as long?).GetValueOrDefault());
break;
case TypeCode.UInt16:
binds.Add(TaosBind.BindSmallInt((tp.Value as short?).GetValueOrDefault()));
binds[i] = TaosBind.BindSmallInt((tp.Value as short?).GetValueOrDefault());
break;
case TypeCode.UInt32:
binds.Add(TaosBind.BindUInt((tp.Value as uint?).GetValueOrDefault()));
binds[i] = TaosBind.BindUInt((tp.Value as uint?).GetValueOrDefault());
break;
case TypeCode.UInt64:
binds.Add(TaosBind.BindUBigInt((tp.Value as ulong?).GetValueOrDefault()));
binds[i] = TaosBind.BindUBigInt((tp.Value as ulong?).GetValueOrDefault());
break;
case TypeCode.String:
default:
binds.Add(TaosBind.BindBinary(tp.Value as string));
binds[i] = TaosBind.BindBinary(tp.Value as string);
break;
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/IoTSharp.Data.Taos/TaosDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ public class TaosDataReader : DbDataReader
List<TDengineMeta> _metas = null;
private double _date_max_1970;
private DateTime _dt1970;
private TAOS_BIND[] _binds;

internal TaosDataReader(TaosCommand taosCommand, List<TDengineMeta> metas, bool closeConnection, IntPtr res, int recordsAffected, int fieldcount)
internal TaosDataReader(TaosCommand taosCommand, List<TDengineMeta> metas, bool closeConnection, IntPtr res, int recordsAffected, int fieldcount, TAOS_BIND[] binds)
{
_taos = taosCommand.Connection._taos;
_command = taosCommand;
Expand All @@ -45,6 +46,7 @@ internal TaosDataReader(TaosCommand taosCommand, List<TDengineMeta> metas, bool
_metas = metas;
_dt1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
_date_max_1970 = DateTime.MaxValue.Subtract(_dt1970).TotalMilliseconds;
_binds = binds;
}

/// <summary>
Expand Down Expand Up @@ -165,6 +167,8 @@ protected override void Dispose(bool disposing)
_command.Connection.Close();
}
TDengine.FreeResult(_taosResult);
if (_binds != null)
TaosBind.FreeTaosBind(_binds.ToArray());
}

/// <summary>
Expand Down