运行我的代码时,我遇到了看似随机的“超出系统资源”异常。我的程序背后的想法是第三方软件不断将数据写入Microsoft Access数据库文件(.res) - 大约每30秒我的代码从此文件读取数据,做一些对它进行操作,并将结果写入我们的数据库。不幸的是,我无法改变第三方软件将数据写入文件的方式,我对Access数据文件感到困惑。
在运行通过Click-Once发布安装的WinForms程序的生产系统以及我的开发系统上的控制台测试程序中都会发生此错误。即使在运行返回单个整数的查询而没有其他程序或线程触及位于本地磁盘上的文件时,我也会收到异常。
异常信息:
System.Data.OleDb.OleDbException (0x80004005): System resource exceeded.
at System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
at System.Data.OleDb.OleDbCommand.ExecuteScalar()
...
重现问题的示例代码:
string connectionString = @"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = C:\datafile.res";
string commandText = "SELECT MIN(Data_Point) FROM Channel_Normal_Table WHERE Test_ID = 1";
int connectionCounter = 0;
object result;
while (true)
{
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
connection.Open();
connectionCounter++;
using (OleDbCommand command = new OleDbCommand(commandText, connection))
{
result = command.ExecuteScalar();
}
connection.Close();
}
}
不幸的是,异常不是确定性的 - 我已经看到它发生在从第4个命令执行到具有相同代码的同一文件的第6149个的任何地方。它总是出现在command.ExecuteScalar()行上。如果此代码中存在资源泄漏,请帮我找到。
我已尝试安装在http://support.microsoft.com/kb/2760394找到的修补程序(并进行了所需的注册表更改),但它无法解决问题。任何建议都会受到赞赏和积极追求。
这是在Windows 7,C#4.0(控制台和WinForms),4 GB RAM
上运行答案 0 :(得分:2)
我会尝试一些事情:
// Share Mode=12 - exclusive mode (16 for multi-user)
string constr = @"Provider=Microsoft.ACE.OLEDB.12.0;" +
"Mode=12;Data Source = C:\datafile.res;user id=;password=;";
private OleDbCommand PermanentCommand;
void KeepLinkOpen() {
if (PermanentCommand == null ||
PermanentCommand.Connection == null ||
PermanentCommand.Connection.State == System.Data.ConnectionState.Closed) {
OleDbConnection conn = new OleDbConnection(connectionString);
conn.Open();
PermanentCommand = new OleDbCommand("SELECT * FROM DummyTable", conn);
PermanentCommand.ExecuteReader(System.Data.CommandBehavior.Default);
}
}
void Disconnect() {
if (PermanentCommand != null) {
if (PermanentCommand.Connection != null) {
PermanentCommand.Connection.Close();
}
PermanentCommand.Dispose();
PermanentCommand = null;
}
}