当 Poolling = true 在 Firebird 2.5.6 上时,C# 应用程序中的连接不会超时
Connection in c# app does not timeout when Poolling = true on Firebird 2.5.6
当我在我的 c# 应用程序上使用带 Pooling=true
的连接字符串连接到 Firebird 2.5.6 SuperServer 时,我断开了网络连接,然后
FbConnection fbc = new FbConnection(connstring);
fbc.Open()
- 永远不会超时,可以等待很长时间并且在这里陷入僵局。
但是当我将连接字符串与 Pooling = false
一起使用时,没关系,几秒钟后代码转到下一行。
另外,当我使用 Pooling = True
和 .Open()
之前时,我会:
FbConnection.ClearAllPools();
比它还好 - 几秒钟后代码转到下一行。
为什么 pooling = true
,如果之前没有清除所有池,我会遇到这个死锁?
你的问题好像不是死锁,而是阻塞的问题(可能是网络问题I/O)。
当您使用 Pooling=true
时,Firebird ADO.net 提供程序保持与服务器的物理连接打开以供重复使用。只有代码中使用的句柄才会关闭。当你打开一个 'new' 连接时,它会首先尝试从池中获取一个物理连接并交给你(可能会做一些验证),如果池中没有连接,它会创建一个新的物理连接。
如果您断开网络连接,现有连接可能仍处于打开状态但不再有效。尝试写入连接可能会成功(由于缓冲区)或阻塞,尝试读取也可能会阻塞。这种阻塞持续多长时间取决于许多因素(断开连接如何发生、网络配置、套接字超时等)。这可能意味着当尝试使用断开连接时已经打开的套接字时,读取或写入可能会无限期地阻塞。如果网络连接恢复,现有连接可能会重新开始工作或可能真的断开,但同样,根据断开连接的性质,恢复或实际失败可能需要一些时间。
另一方面,使用 Pooling=false
将确保每个 FbConnection.Open()
都会创建一个新的物理连接,同样,FbConnection.ClearAllPools()
将删除并关闭现有的物理连接池,强制在后续调用 FbConnection.Open()
时需要新的物理连接。
现在,当这个新的物理连接被创建时,网络堆栈通常会很快检测到远程服务器不可访问,并很快失败,或者 - 如果网络连接已恢复 - 将能够快速连接。
不幸的是,Firebird ADO.net Provider 似乎没有在其套接字上指定 SendTimeout
或 ReceiveTimeout
,这意味着没有办法让它在不存在的情况下更快地失败工作套接字连接。
当我在我的 c# 应用程序上使用带 Pooling=true
的连接字符串连接到 Firebird 2.5.6 SuperServer 时,我断开了网络连接,然后
FbConnection fbc = new FbConnection(connstring);
fbc.Open()
- 永远不会超时,可以等待很长时间并且在这里陷入僵局。
但是当我将连接字符串与 Pooling = false
一起使用时,没关系,几秒钟后代码转到下一行。
另外,当我使用 Pooling = True
和 .Open()
之前时,我会:
FbConnection.ClearAllPools();
比它还好 - 几秒钟后代码转到下一行。
为什么 pooling = true
,如果之前没有清除所有池,我会遇到这个死锁?
你的问题好像不是死锁,而是阻塞的问题(可能是网络问题I/O)。
当您使用 Pooling=true
时,Firebird ADO.net 提供程序保持与服务器的物理连接打开以供重复使用。只有代码中使用的句柄才会关闭。当你打开一个 'new' 连接时,它会首先尝试从池中获取一个物理连接并交给你(可能会做一些验证),如果池中没有连接,它会创建一个新的物理连接。
如果您断开网络连接,现有连接可能仍处于打开状态但不再有效。尝试写入连接可能会成功(由于缓冲区)或阻塞,尝试读取也可能会阻塞。这种阻塞持续多长时间取决于许多因素(断开连接如何发生、网络配置、套接字超时等)。这可能意味着当尝试使用断开连接时已经打开的套接字时,读取或写入可能会无限期地阻塞。如果网络连接恢复,现有连接可能会重新开始工作或可能真的断开,但同样,根据断开连接的性质,恢复或实际失败可能需要一些时间。
另一方面,使用 Pooling=false
将确保每个 FbConnection.Open()
都会创建一个新的物理连接,同样,FbConnection.ClearAllPools()
将删除并关闭现有的物理连接池,强制在后续调用 FbConnection.Open()
时需要新的物理连接。
现在,当这个新的物理连接被创建时,网络堆栈通常会很快检测到远程服务器不可访问,并很快失败,或者 - 如果网络连接已恢复 - 将能够快速连接。
不幸的是,Firebird ADO.net Provider 似乎没有在其套接字上指定 SendTimeout
或 ReceiveTimeout
,这意味着没有办法让它在不存在的情况下更快地失败工作套接字连接。