經過更多研究,我發現解決方案如何停止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