我正在运行一项服务,该服务连接到一些客户端。它已经启动并运行了几周,这个函数每分钟都会被调用很多次,我在不同的函数中有一些捕获,但是这个异常使它一路崩溃。我以前从未见过这个问题。谁能让这一切发生?
堆:
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*)
Run Code Online (Sandbox Code Playgroud)
代码:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
以下部分有点过时,并且涉及 EF6 和 .NET Framework 4.x。如今,如果您使用 .NET (Core),请使用EntityFrameworkCore.Jet EF Core 提供程序。使用最新的预发行版,它引用了 5.0.0 OLE DB 库,其中包含一些主要的错误修复。
此问题是 ACE 2010 引擎中的一个错误。可以在microsoft connect 的原始错误报告中找到解决方法(请参阅 FranzT):
在我的应用程序中我有同样的问题。MS Access DB 是该应用程序的后端(C#、.NET 2.0、VS 2005)。
当在连接字符串中使用提供程序 OLEDB.4.0 时,它工作正常。当数据访问提供程序是 ACE.OLEDB.12 时,如果使用 OpenFileDialog,我会收到异常。
在连接字符串中可以设置许多参数,OLE DB 服务也是如此。
当 OLE DB Services=default(-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 提供程序的其他 AccessViolationException 案例相同。
还有一个据称可以解决该问题的修补程序的链接。
顺便说一句,使用提供程序不会发生此异常Microsoft.Jet.OLEDB.4.0 。
对于像我这样使用bubibubi 的 JetEntityFrameworkProvider的人,请确保您在生产连接字符串中使用解决方法,而不是在用于应用数据库迁移的连接字符串中使用,因为它会OleDbException E_UNEXPECTED(0x8000FFFF)在第二个 Update-Database 命令上抛出尝试打开数据库时,此后每次执行命令时都会锁定包管理器控制台(直到重新启动 Visual Studio)。
访问是为通过网络共享同时进行多用户访问而构建的。所以这是一个明确支持的场景。@汉斯·帕桑特和@user2905764
小智 0
为什么不使用这个让它变得更简单呢?如果将连接、命令和读取器对象包装在using语句块内,那就太好了。请参阅 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;
}
Run Code Online (Sandbox Code Playgroud)