AccessViolationException on service

北战南征 提交于 2020-07-19 04:53:24

问题


I have a service running, that is connected to a few clients. It has been up and running for weeks and this function is called many times every minute, I have a few catches in the different function, but this exception made it all the way to crash. I never seen the issue before. Whan can make this occure?

Stack:

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*)

Code:

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;
            }
        }

回答1:


AccessViolationException

This issue is a bug within the ACE 2010 engine. A workaround can be found in the original bug report on microsoft connect (see FranzT):

In my Applicationn I have the same problem. MS Access DB is a backend for this app(C#, .NET 2.0, VS 2005).

When in connection string as provider OLEDB.4.0 is used, it works fine. When the data access provider is ACE.OLEDB.12 I get an Exception if OpenFileDialog is used.

In connection string is possibel to set many parameters, OLE DB Services too.

When OLE DB Services=default (-13, pooling disabled) I get the Exception. When OLE DB Services=EnableAll (-1, pooling enabled) it works fine.

If I set OLE DB Services=-2 (EnableAll without pooling) I get the Exception.

My workaround is: set the OLE DB services=-1(EnableAll).

The workaround is based on the research of a microsoft forum user by the name of Elmar Boye, who goes into detail about the nature of the issue (though in German):

https://social.msdn.microsoft.com/Forums/de-DE/500055e5-6189-418c-b119-fdc0367e0969/accessviolationexception-bei-openfiledialog-nach-ffnen-und-schlieen-einer-2-form?forum=dotnetframeworkde

Basically, the ACE 2010 engine is accessing memory it doesn't own. And if the database is already unloaded at the time the engine accesses the memory, the exception is thrown. To workaround the issue, connection pooling can be used, since it keeps the database connection open and therefore the database in memory. It can be enabled using different combinations of OLE DB Services flags.

A good flag value is the original default, which enables all services (though this default seems to be overwritten by a registry key, which is why it makes sense to manually provide the value in the connection string):

OLE DB Services=-1

Though the bug report addresses a problem within the open file dialog, the root cause is the same as for other AccessViolationException cases using the ACE 2010 provider for Access.

There is also a link to a Hotfix that supposedly fixes the issue.

By the way, this exception does not occur using the Microsoft.Jet.OLEDB.4.0 provider.

JetEntityFrameworkProvider

For those like me who are using the JetEntityFrameworkProvider by bubibubi make sure that you are using the workaround in your production connection string, but not in your connection string you use for applying database migrations, because it will throw a OleDbException E_UNEXPECTED(0x8000FFFF) on the second Update-Database command while trying to open the database and will lockup the Package Manager Console on every command execution thereafter (until you restart Visual Studio).

Access and multi user scenarios

Access is build for simultaneous multi user access over a network share. So this is a scenario that is explicitly supported. @Hans Passant and @user2905764




回答2:


Why dont you make it more sumpler by using this. If would greate if you wrap connection, command and reader objects inside a using statement block. See usage of using.

Update

Sorry , I saw this couple of minutes ago that, you are using Access db for Services, which is, I think completely insane. Since services are consumed by various clients at a time so it might lead to inconsistency. So, as Hans Passant suggested in his comment, kindly go for Sql Server Express or MySql like Server-Oriented database for such scenarios.

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;
        }


来源:https://stackoverflow.com/questions/19516640/accessviolationexception-on-service

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!