经过更多研究,我发现解决方案如何停止OutOfMemoryException并采取预期的TimeoutException。
由于存储过程中使用PRINT,所以这种情况下内存正在增长。 Driever正在收集数据库的默认输出。因此,如果用户没有阅读此内容,则可能会发生OutOfMemoryException。
根据你想要的结果可以使用两种解决方案。当数据库输出是不是对你很重要,当执行需要长期您所期待Timout
第一个是好的。下面摘录解决了这个问题的方式:
public void CallProcedure()
{
// Line below release all Errors/PRINT output from command. Command is now
// not collecting them, so memory is not growing.
// CommandTimeout will be thrown after preset value on command object.
this._connection.FireInfoMessageEventOnUserErrors = true;
SqlCommand cmd = this._connection.CreateCommand();
cmd.CommandTimeout = 15;
cmd.CommandType = CommandType.StoredProcedure;
command.CommandText = 'InfiniteLoop';
//Line below throws OutOfMemoryException
cmd.ExecuteNonQuery();
cmd.Dispose();
}
第二个是goog当您要执行,可以采取大量的时间真的耗时的过程。超时异常将永远不会发生。要启用此行为,您需要在SqlConnection中的InfoMessage上附加SqlInfoMessageEventHandler。请参阅下面的代码片段:
public void CallProcedure()
{
// By attaching this event no Timeout exception on ExecuteNonQuery occur
// Your ExecuteNonQuery can hang infinitly!
// If you need Timeout then you need to write you own handler from different thread
this._connection.InfoMessage += new SqlInfoMessageEventHandler(OnInfoMessage);
// Line below release all Errors/PRINT output from command. Command is now
// not collecting them so memory is not growing.
this._connection.FireInfoMessageEventOnUserErrors = true;
SqlCommand cmd = this._connection.CreateCommand();
// In this case Timeout will never occur
cmd.CommandTimeout = 15;
cmd.CommandType = CommandType.StoredProcedure;
command.CommandText = 'InfiniteLoop';
//Line below throws OutOfMemoryException
cmd.ExecuteNonQuery();
cmd.Dispose();
this._connection.InfoMessage -= new SqlInfoMessageEventHandler(OnInfoMessage);
}
void OnInfoMessage(object sender, SqlInfoMessageEventArgs e)
{
System.Diagnostics.Debug.WriteLine(DateTime.Now.ToString()+": "+ e.Message);
}
看起来您已经发现了一个关于ExecuteNonQuery实现的有趣观点。但是你的问题是什么? – 2013-03-19 13:10:01