在通过APM处理异步代码时是否应保持我的SqlConnection处于打开状态?
我正在创建一个应用程序(它是一个服务器),它使用套接字接收来自不同客户端(聊天服务器)的数据并可以访问数据库(Microsoft SQL Server)。在通过APM处理异步代码时是否应保持我的SqlConnection处于打开状态?
服务器更新循环看起来是这样的:
void UpdateLoop()
{
while(true)
{
ReceiveData();
ProcessData();
}
}
每次我收到来自客户端的数据(字符串),这个数据将使用存储过程来保存到数据库中。由于它是单线程的,我想,以避免阻塞操作,我选择使用异步编程模型(APM):
void ProcessData()
{
var command = new SqlCommand("stored_procedure_name", _connection);
command.CommandType = CommandType.StoredProcedure;
command.BeginExecuteNonQuery(CommandCallback, command);
/*at this point, we return to the UpdateLoop method and
the command keeps running asynchronously, avoid blocking
the whole thread and processing other requests.*/
}
void CommandCallback(IAsyncResult ar)
{
var command = (SqlCommand)ar.AsyncState;
command.EndExecuteNonQuery(ar);
}
正如你可以在上面看到,该_connection变量表示的SqlConnection类,保持与数据库的连接。我在应用程序的开始处打开连接,并且只在应用程序结束时关闭连接。
我读过它的更好(和良好的编码习惯)打开仅在需要时连接和使用语句中使用后立即处置它,与,就像这样:
using(var connection = new SqlConnection("..."))
{
//create the command and execute it (synchronously)
}
但我认为不能使用使用声明与我当前的代码,因为它必须是异步的。
是否可以让sql连接全部打开?如果不是,这种情况下更好的解决方案是什么?
规则很清楚:打开连接并尽快关闭它)当然简而言之。我最近和你做过类似的聊天,我不在意连接。我需要时打开它,并在获取数据后关闭它。主要原因是,当应用程序打开连接时,实际上并不是真的......打开它。奇怪?不是真的。有像连接池这样的连接可以使用的连接。物理开放连接到数据库需要很长时间,因此提到池已被“发明”。如果您的聊天会越来越流行,请尝试切换网络套接字。
感谢您的回应!但是,如何关闭我的情况下的连接,因为它是异步的(APM)?我应该关闭CommandCallback方法上的连接吗?如果有数千个请求正在同时处理呢? – hendoe
离开连接建立通常并不是什么大事,只要它只是闲置,而不是让交易开放。与建立到数据库的连接相关的成本是非零的,所以如果你的流量很大,每分钟关闭和重新打开数千次的连接将开始引人注目。在这种情况下,最好离开建立的连接。 – Xedni
只要您完成资源处理,即可处理您的资源。 Sql连接池将在您需要重新建立连接时尽快处理优先级。 – Kyle