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