C# gcnew 对象和 long 运行 SQL 查询
C# gcnew object and long running SQL query
我有一个 select 和 运行 一个 SQL 查询的过程。有时(大多数情况下它工作正常)这会导致原始调用函数结束时崩溃。过程是这样的(实例化的所有方法调用类); (注意;由于实际代码有 1000 行,所以只列出流程。如果需要,我会尝试提供更多细节)
对 QueryPicker 的方法调用(参数)(c#)
QueryPicker 调用 cs_query_picker (params) (c++, 在加载的 dll 中,当时由其他服务共享)
cs_query_picker 声明 100 个变量然后调用 QueryPickerWrapper (params) (c#)
QueryPickerWrapper 使用 gcnew
string ^Params = gcnew string;
if (param != nullptr)
Params->Str = gcnew String (params);
QueryPickerWrapper 然后调用 MyQueryPicker (Params) //made with gcnew
这会找到 SQL 查询并 运行s 它。它最多可能需要 1200 毫秒(真的不是很长)
MyQueryPicker 然后设置 Params(带有查询结果)和 returns true(设置的东西)
QueryPickerWrapper 当返回 true 时,设置指针
if(params != nullptr)
strcpy_s(params, PARAM_LEN+1, (char*)(void*)Marshal::StringToHGlobalAnsi(Params->Str));
QueryPickerWrapper 然后 returns true
cs_query_picker returns 当它从 QueryPickerWrapper 获得 1 时为 1,否则它会移动到旧代码(1998 年的东西,将使用 100 多个声明的变量)来设置参数。在所有崩溃中,QueryPickerWrapper 总是 returns a 1.
QueryPicker 收到 1,使用传回的参数完成方法,然后崩溃。
我从来没有发现崩溃的异常(我有一个 try/catch 围绕它)和 windows 事件日志,它说
故障模块名称:clr.dll、version:4.0.30319.34209
异常代码:0xc00000fd
故障偏移量:0x001a149f
根据我的研究,这是堆栈溢出。但是,我不知道它会如何发生。我跌倒了,因为这个问题是间歇性的(有时也是每小时一次,有时不是几天),这是垃圾收集器 运行 的时间与 SQL 调用在返回之前需要多长时间之间的关系。
问题:
这是怎么发生的,我该如何解决?
这是在 .NET4.0
中编译和 运行
string ^Params = gcnew string;
if (param != nullptr)
Params->Str = gcnew String (params);
我无法判断这里有什么错字,什么可能是编码问题。
Params = gcnew string
,接着是Params->Str
。 System::String
nor std::string
都没有名为 Str
的成员。 Params 是一个结构体还是类似的东西?
Params
、param
和 params
。你有三个几乎相同命名的变量。如果它们都是彼此的错别字,那么我不知道 params->Str = gcnew String(params);
应该做什么。
.
strcpy_s(params, PARAM_LEN+1, (char*)(void*)Marshal::StringToHGlobalAnsi(Params->Str));
好的,这个我可以回答。您的主要问题是您在 StringToHGlobalAnsi
中分配了一个新的 HGlobal,并且从不释放它(内存泄漏)。您可以保留指针并释放它,但我更喜欢使用 std::string
作为临时变量。每个人都知道如何处理 std::string
,所以没有新的规则需要学习。
#include <msclr/marshal_cppstd.h>
std::string temp = marshal_as<std::string>(source);
strcpy_s(destination, PARAM_LEN+1, temp->c_str());
我有一个 select 和 运行 一个 SQL 查询的过程。有时(大多数情况下它工作正常)这会导致原始调用函数结束时崩溃。过程是这样的(实例化的所有方法调用类); (注意;由于实际代码有 1000 行,所以只列出流程。如果需要,我会尝试提供更多细节)
对 QueryPicker 的方法调用(参数)(c#)
QueryPicker 调用 cs_query_picker (params) (c++, 在加载的 dll 中,当时由其他服务共享)
cs_query_picker 声明 100 个变量然后调用 QueryPickerWrapper (params) (c#)
QueryPickerWrapper 使用 gcnew
string ^Params = gcnew string;
if (param != nullptr)
Params->Str = gcnew String (params);
QueryPickerWrapper 然后调用 MyQueryPicker (Params) //made with gcnew
这会找到 SQL 查询并 运行s 它。它最多可能需要 1200 毫秒(真的不是很长)
MyQueryPicker 然后设置 Params(带有查询结果)和 returns true(设置的东西)
QueryPickerWrapper 当返回 true 时,设置指针
if(params != nullptr)
strcpy_s(params, PARAM_LEN+1, (char*)(void*)Marshal::StringToHGlobalAnsi(Params->Str));
QueryPickerWrapper 然后 returns true
cs_query_picker returns 当它从 QueryPickerWrapper 获得 1 时为 1,否则它会移动到旧代码(1998 年的东西,将使用 100 多个声明的变量)来设置参数。在所有崩溃中,QueryPickerWrapper 总是 returns a 1.
QueryPicker 收到 1,使用传回的参数完成方法,然后崩溃。
我从来没有发现崩溃的异常(我有一个 try/catch 围绕它)和 windows 事件日志,它说
故障模块名称:clr.dll、version:4.0.30319.34209
异常代码:0xc00000fd
故障偏移量:0x001a149f
根据我的研究,这是堆栈溢出。但是,我不知道它会如何发生。我跌倒了,因为这个问题是间歇性的(有时也是每小时一次,有时不是几天),这是垃圾收集器 运行 的时间与 SQL 调用在返回之前需要多长时间之间的关系。
问题: 这是怎么发生的,我该如何解决?
这是在 .NET4.0
中编译和 运行string ^Params = gcnew string;
if (param != nullptr)
Params->Str = gcnew String (params);
我无法判断这里有什么错字,什么可能是编码问题。
Params = gcnew string
,接着是Params->Str
。System::String
norstd::string
都没有名为Str
的成员。 Params 是一个结构体还是类似的东西?Params
、param
和params
。你有三个几乎相同命名的变量。如果它们都是彼此的错别字,那么我不知道params->Str = gcnew String(params);
应该做什么。
.
strcpy_s(params, PARAM_LEN+1, (char*)(void*)Marshal::StringToHGlobalAnsi(Params->Str));
好的,这个我可以回答。您的主要问题是您在 StringToHGlobalAnsi
中分配了一个新的 HGlobal,并且从不释放它(内存泄漏)。您可以保留指针并释放它,但我更喜欢使用 std::string
作为临时变量。每个人都知道如何处理 std::string
,所以没有新的规则需要学习。
#include <msclr/marshal_cppstd.h>
std::string temp = marshal_as<std::string>(source);
strcpy_s(destination, PARAM_LEN+1, temp->c_str());