Search code examples
c#ms-accessoledboledbconnection

System.Runtime.InteropServices.SEHException - in OleDb Connection using C#


We are connecting to Access DB via OLE DB Connection and it was working till last office update. Now after getting latest version of MS Office

System.Runtime.InteropServices.SEHException: 'External component has thrown an exception.'

My build configuration is x86 and Access database engine also 32 bit. So, as a solution i have repaired the access engine and it starts working. But, i am able to reproduce the issue with below code

static void Main(string[] args)
        {

            var _conStr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\test.accdb; Persist Security Info=False";

            try
            {


                Task.Run(() =>
                {
                    using (var con = new OleDbConnection(_conStr))
                    {
//This Call 1
                        con.Open();
                    }
                });


                using (OleDbConnection OleDbConnection = new System.Data.OleDb.OleDbConnection(_conStr))
                {


// This Call 2
                    OleDbConnection.Open();
                }


                Console.WriteLine("Hello World 1!");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.WriteLine("Hello World 2!");
            Console.ReadKey();
        }
    }

In the call 2 only i am getting this exception. But, most confusing thing is, how does it has the issue with latest update. How come its working if i repair access database engine.

What is the fix for above code? I used many tasks in my application.

Thanks in advance


Solution

  • As far as its causing issue only in multi threading. So that, we have handled the issue in Thread safe calls. Please refer below.

    class Program
    {
        static object synObj = new object();
    
        static string _conStr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\test.accdb;Jet OLEDB:Database Password=1234567;";
    
        static OleDbConnection _oleDBObject;
        public static OleDbConnection OleDBObject
        {
            get
            {
                lock (synObj)
                {
                    if (_oleDBObject != null && _oleDBObject.State == System.Data.ConnectionState.Open)
                    {
    
                        return _oleDBObject;
    
                    }
                    else
                    {
                        _oleDBObject = new OleDbConnection(_conStr);
                        _oleDBObject.Open();
                        return _oleDBObject;
                    }
                }
            }
        }
    
    
        static void Main(string[] args)
        { 
            try
            {
    
                int i = 0;
    
                while (i < 10)
                {
                    Task.Run(() =>
                    {
    
                        // Connection inside task
                        var con = OleDBObject;
                        Console.WriteLine("Inside Task -" + i.ToString());
    
                    });   
    
                    i++;
    
                    Console.WriteLine("Task -" + i.ToString());
    
                }
    
                // Connection outside task
                OleDbConnection OleDbConnection = OleDBObject;
    
    
                Console.WriteLine("Hello World 1!");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
    
            Console.ReadKey();
        }
    
    
    }