Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 服务上的AccessViolationException异常_C#_Service - Fatal编程技术网

C# 服务上的AccessViolationException异常

C# 服务上的AccessViolationException异常,c#,service,C#,Service,我有一个正在运行的服务,它连接到几个客户端。它已经启动并运行了几个星期,这个函数每分钟都被调用很多次,我在不同的函数中遇到了一些问题,但是这个异常使它一路崩溃。我以前从未见过这个问题。什么能使这发生 堆栈: Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.AccessViolationExcepti

我有一个正在运行的服务,它连接到几个客户端。它已经启动并运行了几个星期,这个函数每分钟都被调用很多次,我在不同的函数中遇到了一些问题,但是这个异常使它一路崩溃。我以前从未见过这个问题。什么能使这发生

堆栈:

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*)
代码:


你为什么不用这个使它更豪华呢。如果使用语句块将连接、命令和读取器对象包装在
中,则If将变大

更新 对不起,几分钟前我看到了,你正在使用Access db进行服务,我认为这是完全疯狂的。因为服务一次被不同的客户机使用,所以可能会导致不一致。因此,正如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;
        }
EF核心更新 以下部分有点过时,是关于EF6和.NETFramework4.x的。 现在,如果您使用.NET(Core),请使用EF Core提供程序。使用最新的预发行版,它引用了5.0.0OLEDB库,其中包含一些主要的错误修复

AccessViolationException 此问题是ACE 2010引擎中的一个bug。可以在中找到解决方法(参见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=enablell(-1,启用池)时 很好

如果我将OLEDB服务设置为-2(EnableAll而不使用池),我会得到异常

我的解决方法是:将OLEDB服务设置为-1(EnableAll)

解决方案基于一位名叫Elmar Boye的microsoft论坛用户的研究,他详细介绍了问题的性质(尽管是德语):

基本上,ACE 2010引擎正在访问它不拥有的内存。如果在引擎访问内存时数据库已经卸载,则抛出异常。为了解决这个问题,可以使用连接池,因为它使数据库连接保持打开状态,从而将数据库保存在内存中。可以使用
OLE DB服务的不同组合启用它

好的标志值是原始默认值,它启用所有服务(尽管此默认值似乎被注册表项覆盖,这就是为什么手动在连接字符串中提供该值的原因):

OLE DB服务=-1

尽管错误报告解决了“打开文件”对话框中的问题,但根本原因与使用ACE 2010提供程序进行访问的其他AccessViolationException情况相同

还有一个链接指向一个据说可以解决这个问题的方法

顺便说一下,使用
Microsoft.Jet.OLEDB.4.0
提供程序不会发生此异常

JetEntityFrameworkProvider 对于像我这样使用的人,请确保您在生产连接字符串中使用了变通方法,而不是在用于应用数据库迁移的连接字符串中使用,因为它将抛出一个意外的OLEDBEException(0x8000FFFF)
在尝试打开数据库时,在执行第二个更新数据库命令时,将锁定此后每次执行命令时的Package Manager控制台(直到重新启动Visual Studio)

访问和多用户场景 访问是为通过网络共享同时进行多用户访问而构建的。这是一个明确支持的场景。
@Hans Passant和@user2905764

在多用户服务场景中使用Access数据库是非常不明智的。对于这样的应用来说,它只是不够防弹而已。您需要Microsoft支持部门的帮助才能找到解决方案,他们至少需要一个小型转储。但他们很可能会告诉你停止这样做,因为他们不支持。至少考虑SQLServer Express作为替代品。
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;
        }