我有一个正在运行的服务,它连接到一些客户端。它已经启动并运行了几个星期,这个函数每分钟被调用很多次,我在不同的函数中有几个捕获,但这个异常使它一直崩溃。我以前从未见过这个问题。 Whan可以发生这种情况吗?
堆栈:
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
Stack:
at System.Data.OleDb.OleDbServicesWrapper.GetDataSource(System.Data.OleDb.OleDbConnectionString, System.Data.OleDb.DataSourceWrapper ByRef)
at System.Data.OleDb.OleDbConnectionInternal..ctor(System.Data.OleDb.OleDbConnectionString, System.Data.OleDb.OleDbConnection)
at System.Data.OleDb.OleDbConnectionFactory.CreateConnection(System.Data.Common.DbConnectionOptions, System.Object, System.Data.ProviderBase.DbConnectionPool, System.Data.Common.DbConnection)
at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(System.Data.Common.DbConnection, System.Data.ProviderBase.DbConnectionPoolGroup)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(System.Data.Common.DbConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(System.Data.Common.DbConnection, System.Data.ProviderBase.DbConnectionFactory)
at System.Data.OleDb.OleDbConnection.Open()
at EServer.Database.DBManager.DoesObjectExsist(System.String)
at EServer.Database.DBManager.setObjectOnline(System.String, Boolean, System.String, System.String)
at EServer.Network.SocketListener.handleToDo()
at EServer.Network.Token.ProcessData(System.Net.Sockets.SocketAsyncEventArgs)
at EServer.Network.SocketListener.ProcessReceive(System.Net.Sockets.SocketAsyncEventArgs)
at EServer.Network.SocketListener.OnIOCompleted(System.Object, System.Net.Sockets.SocketAsyncEventArgs)
at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(System.Net.Sockets.SocketAsyncEventArgs)
at System.Net.Sockets.SocketAsyncEventArgs.ExecutionCallback(System.Object)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationSuccess(System.Net.Sockets.SocketError, Int32, System.Net.Sockets.SocketFlags)
at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
代码:
public bool DoesObjectExsist(String ID)
{
try
{
String connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + dbPath + "'";
string mySelectQuery = "SELECT * FROM Object WHERE ID = \"" + ID + "\"";
OleDbConnection myConnection = new OleDbConnection(connectionString);
OleDbCommand myCommand = new OleDbCommand(mySelectQuery, myConnection);
myConnection.Open();
OleDbDataReader myReader = myCommand.ExecuteReader();
try
{
while (myReader.Read())
{
return true;
}
}
finally
{
myReader.Close();
myConnection.Close();
}
return false;
}
catch (Exception e)
{
return false;
}
}
答案 0 :(得分:0)
为什么不用这个让它变得更加丰富。如果将using
语句块中的连接,命令和读取器对象包装起来,那么会更好。 See usage of using.
对不起,我在几分钟前看到,你正在使用Access db for Services,我认为这完全是疯了。由于服务一次被各种客户端使用,因此可能导致不一致。因此,正如Hans Passant在他的评论中所建议的那样,请注意Sql Server Express
或MySql
类似于面向服务器的数据库。
public bool DoesObjectExsist(String ID)
{
bool result=false;
try
{
String connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" + dbPath + "'";
string mySelectQuery = "SELECT Count(*) FROM Object WHERE ID = ?";
OleDbConnection myConnection = new OleDbConnection(connectionString);
OleDbCommand myCommand = new OleDbCommand(mySelectQuery, myConnection);
command.Parameters.AddWithValue("@id",ID);
myConnection.Open();
OleDbDataReader myReader = myCommand.ExecuteReader();
try
{
if(reader.HasRows)
result=true;
}
finally
{
myReader.Close();
myConnection.Close();
}
}
catch (Exception e)
{
//log exception
}
return result;
}
答案 1 :(得分:0)
此问题是ACE 2010引擎中的错误。可以在original bug report on microsoft connect中找到解决方法(参见FranzT):
在我的应用程序中,我遇到了同样的问题。 MS Access DB是此应用程序的后端(C#,. NET 2.0,VS 2005)。
当使用连接字符串作为提供者OLEDB.4.0时,它工作正常。当数据访问提供程序是ACE.OLEDB.12时,如果使用OpenFileDialog,则会出现异常。
在连接字符串中可以设置许多参数,OLE DB服务也是如此。
当OLE DB服务=默认(-13,池已禁用)时,我得到了 例外。当OLE DB Services = EnableAll(-1,池启用)时 工作正常。
如果我设置OLE DB Services = -2(EnableAll没有合并),我会得到异常。
我的解决方法是:设置OLE DB服务= -1(EnableAll)。
该解决方法基于一个名为Elmar Boye的微软论坛用户的研究,他详细介绍了该问题的性质(尽管用德语):
基本上,ACE 2010引擎正在访问它不拥有的内存。如果在引擎访问内存时数据库已经卸载,则抛出异常。要解决此问题,可以使用连接池,因为它可以使数据库连接保持打开状态,从而使数据库保持在内存中。可以使用OLE DB Services
标志的不同组合启用它。
一个好的标志值是原始默认值,它启用所有服务(虽然这个默认值似乎被注册表项覆盖,这就是为什么在连接字符串中手动提供值是有意义的):
OLE DB Services=-1
虽然错误报告解决了打开文件对话框中的问题,但根本原因与使用ACE 2010提供程序进行Access的其他AccessViolationException情况相同。
还有Hotfix的链接可以解决问题。
顺便说一句,使用Microsoft.Jet.OLEDB.4.0
提供程序不会发生此异常。
对于像我这样使用JetEntityFrameworkProvider by bubibubi的人,请确保您在生产连接字符串中使用变通方法,而不是在用于应用数据库迁移的连接字符串中,因为它会抛出{{}尝试打开数据库时,在第二个Update-Database命令上运行,并在此后的每个命令执行时锁定Package Manager控制台(直到重新启动Visual Studio)。
构建访问权限,以便通过网络共享同时进行多用户访问。所以这是一个明确支持的场景。 @Hans Passant和@ user2905764