小编Lux*_*782的帖子

SQLite/C#连接池和准备语句混淆

我花了一些时间专门为数据库和SQLite阅读不同的最佳实践.在阅读时我发现我做了很多我不应该做的事情,在尝试修复这些问题时,我在考虑使用SQLite及其ADO实现的一些更精细的细节时感到困惑.

我的困惑源于准备好的陈述和连接池.

在阅读http://msdn.microsoft.com/en-us/library/ms971481.aspx时,我发现只应为事务打开连接.交易完成后,应关闭连接.我没有牢牢掌握为什么会这样,但我一直在假设作者知道的比我更好.我明白当连接关闭时并不意味着它实际上已经存在已经关闭.它只是意味着它已被放回池中.

现在,为了改进我的查询和插入,我阅读了有关使用预准备语句 在SQLite中,准备好的语句真的能提高性能吗?http://petesbloggerama.blogspot.com/2007/02/sqlite-adonet-prepared-statements.html似乎都表明,当执行多次执行的查询时,准备好的语句是可行的.我还读过,预准备语句特定于连接,并且一旦连接关闭,预准备语句就会丢失.

我的困惑是这个.如果我打开和关闭我的连接(可能或不可能意味着由于线程池而关闭连接)那么我从准备好的声明中获得了多少用处?我可以理解,如果我有1000个对象,我需要在单个事务中保存,准备好的语句可以帮助很多.但是我不相信我会看到在事务中保存单个对象会带来好处,因为一旦我关闭了连接,从第一个对象生成的预准备语句现在就会丢失.这是真实的陈述吗?

我相信准备好的语句与我的SQLiteCommand对象的范围有关,这进一步加剧了我的困惑.

如果我创建一个表示我将经常执行的查询的SQLiteCommand,我是否需要将SQLiteCommand保留在内存中以使预准备语句保持活动状态?

如果我用相同的SQLite语句创建一个新的SQLiteCommand,它是否认识到新的SQLiteCommand与前一个相同,因此有一个可以使用的预准备语句?

如果我在内存中保留一个SQLiteCommand并更改它的参数和连接,因为我打开并关闭不同事务的连接,我基本上在不同的连接之间保持一个准备好的语句?

我很可能在这一点上思考问题,但我希望你能帮助我更好地理解这些事情是如何相互作用的,这样我才能从中获益最多.

c# sqlite connection-pooling prepared-statement

32
推荐指数
2
解决办法
1万
查看次数

非托管回调导致堆栈溢出

我正在使用C#的非托管资源.该资源公开了一个回调,可以为硬件中可能发生的某些事件设置回调.要访问非托管函数,请执行以下操作:

[DllImportAttribute("testDLL.dll", EntryPoint = "InstallCallback")]
public static extern short InstallCallback(uint handle, byte x, byte y, IntFuncPtr ptr);

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void IntFuncPtr(uint handle, byte x, byte y, LogEntry info);
Run Code Online (Sandbox Code Playgroud)

我首先使用对IntFuncPtr委托之后的方法的引用来安装回调.然后我让硬件去做它的事情.在大约4700次回调调用之后,应用程序崩溃了.如果我用c/c ++编写代码,回调工作正常,但我可以通过从回调函数中删除__stdcall来复制它.从C#我无法捕获指示应用程序在非托管资源中死亡的错误.使用c/c ++应用程序,我可以看到堆栈溢出而没有__stdcall.

我认为委托可能无法使用调用约定stdcall,所以我尝试了以下内容:

[DllImportAttribute("testDLL.dll", EntryPoint = "InstallCallback")]
public static extern short InstallCallback(uint handle, byte x, byte y, IntPtr ptr);

public delegate void IntFuncPtr(uint handle, byte x, byte y, LogEntry info);

var callBackDelegate = new IntFuncPtr(Callback);
var callBackPtr = Marshal.GetFunctionPointerForDelegate(callBackDelegate);
InstallCallback(handle, 1, 1, callBackPtr);
Run Code Online (Sandbox Code Playgroud)

这也行不通.

总而言之,我有一个非托管回调,它需要一个指向定义为__stdcall的函数的函数指针.如果函数指针指向非__stdcall函数,则堆栈会增长并溢出.我试图使用DllImport在C#中使用回调,并使用stdcall调用约定来使用UnmanagedFunctionPointer委托.当我这样做时,C#应用程序就像使用非__stdcall函数的ac/c ++应用程序.

如何让它完全在C#中工作?

编辑1:

这是本机方法定义和结构信息,包括C#结构信息.

extern …
Run Code Online (Sandbox Code Playgroud)

c c# unmanaged callback .net-4.0

5
推荐指数
1
解决办法
451
查看次数