In Access 2016, for high frequency access, creating an instance of OLEDB connection for each access may cause the client application to crash

taisei ishiyama 1 Reputation point
2021-02-16T09:12:04.78+00:00

Hello everyone.
I would like to ask a question about Access 2016.
I am using Access 2016 from an application created in C# using an OLEDB provider.
When I create a connection instance for every access, the application crashes. The frequency is about once every half day.
The code is as follows

private void button1_Click(object sender, EventArgs e)
{
Task.Run(async () =>
{
var i = 0;
while (true)
{
using var connection = new OleDbConnection(_connectionString);
await connection.OpenAsync();
using var commend = new OleDbCommand(_query, connection);
_ = await commend.ExecuteNonQueryAsync();
Invoke((MethodInvoker)(() => textBox1.Text = (++i).ToString()));
await Task.Delay(100);
}
});
}

I have also found that this problem can be remedied by making sure to reuse the connection.

private void button2_Click(object sender, EventArgs e)
{
Task.Run(async () =>
{
var i = 0;
while (true)
{
if (_connection == default(OleDbConnection))
{
_connection ?? = new OleDbConnection(_connectionString2);
await _connection.OpenAsync();
}
using var commend = new OleDbCommand(_query, _connection);
_ = await commend.ExecuteNonQueryAsync();
Invoke((MethodInvoker)(() => textBox1.Text = (++i).ToString()));
await Task.Delay(100);
}
});
}

I would like to know for the sake of later learning, is the above usage not recommended in Access 2016?
Thank you very much.

Added on 2021-02-17

I'm sorry that there was a problem with my code.
I tried modifying it to use the Using block, but that didn't solve the problem and caused the crash.

private void button1_Click(object sender, EventArgs e)
            {
                Task.Run(async () =>
                {
                    var i = 0;
                    while (true)
                    {
                        using (var connection = new OleDbConnection(_connectionString))
                        {
                            await connection.OpenAsync();
                            using (var commend = new OleDbCommand(_query, connection))
                            {
                                _ = await commend.ExecuteNonQueryAsync();
                                Invoke((MethodInvoker)(() => textBox1.Text = (++i).ToString()));
                            }
                        }

                        await Task.Delay(100);
                    }
                });
            }

Added on 2021-02-18
Added a try catch clause to check for exceptions. However, I could not catch the exception and it crashed.

[HandleProcessCorruptedStateExceptions()]
        private void button1_Click(object sender, EventArgs e)
        {
            Task.Run(async () =>
            {
                var i = 0;
                while (true)
                {
                    try
                    {
                        using (var connection = new OleDbConnection(_connectionString))
                        {
                            await connection.OpenAsync();
                            using (var commend = new OleDbCommand(_query, connection))
                            {
                                _ = await commend.ExecuteNonQueryAsync();
                                Invoke((MethodInvoker)(() => textBox1.Text = (++i).ToString()));
                            }
                        }
                    }
                    catch
                    {
                        Debug.WriteLine("error");
                    }

                    await Task.Delay(100);
                }
            });
        }
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,906 questions
Access Development
Access Development
Access: A family of Microsoft relational database management systems designed for ease of use.Development: The process of researching, productizing, and refining new or existing technologies.
877 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Ken Tucker 5,851 Reputation points
    2021-02-16T11:45:20.4+00:00

    I think you are running out of available connections. I would change the code to this. I think the using block will make sure the connection is closed when you are done with it.

    {
         using( var connection = new OleDbConnection(_connectionString))   
         {
                await connection.OpenAsync();
                using( var commend = new OleDbCommand(query, connection))
                {
                       var data = await commend.ExecuteNonQueryAsync();
                        Invoke((MethodInvoker)(() => textBox1.Text = (++i).ToString()));
                 }
         }
        await Task.Delay(100);
    

    }


  2. Karen Payne MVP 35,421 Reputation points
    2021-02-16T12:59:27.55+00:00

    Here is a start of a code flow to consider which uses events for reporting success and if an exception is thrown. The two events in the form need actions e.g. show in a MessageBox on finished if successful or not while the exception event indicates the exception by reading the exception message.

    Data class

    using System;
    using System.Data.OleDb;
    using System.Threading.Tasks;
    
    namespace OleDbConnectionUpdateData
    {
        public class DataOperations
        {
            private static string _connectionString = "TODO";
    
            public delegate void OnFinish();
            public static event OnFinish OnFinishedEvent;
    
            public delegate void OnException(Exception sender);
            public static event OnException OnExceptionEvent;
    
            public static async Task<bool> PerformUpdateTask()
            {
    
                return await Task.Run(async () =>
                {
                    using (var cn = new OleDbConnection(_connectionString))
                    {
    
                        using (var cmd = new OleDbCommand() { Connection = cn })
                        {
    
                            cmd.CommandText = "TODO";
    
                            try
                            {
                                await cn.OpenAsync();
                                var result = await cmd.ExecuteNonQueryAsync();
                                OnFinishedEvent?.Invoke();
                                return result == 1;
                            }
                            catch (Exception ex)
                            {
                                OnExceptionEvent?.Invoke(ex);
                                return false;
                            }
                        }
                    }
    
                });
            }
    
        }
    }
    

    Form code

    Note I don't pass anything to the update method, that you can handle.

    using System;
    using System.Windows.Forms;
    
    namespace OleDbConnectionUpdateData
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
    
                DataOperations.OnExceptionEvent += OnExceptionEvent;
                DataOperations.OnFinishedEvent += OnFinishedEvent;
            }
    
            private void OnFinishedEvent()
            {
    
            }
    
            private void OnExceptionEvent(Exception sender)
            {
    
            }
    
            private async void button1_Click(object sender, EventArgs e)
            {
                var result = await DataOperations.PerformUpdateTask();
                if (result)
                {
    
                }
                else
                {
    
                }
            }
        }
    }
    

  3. Daniel Zhang-MSFT 9,626 Reputation points
    2021-03-01T09:10:53.5+00:00

    Hi taiseiishiyama-8785,
    You can try to create an async Task method.
    Please refer to the following code:

    private void button1_Click(object sender, EventArgs e)  
    {  
        test();  
    }  
    async Task test()   
    {  
        var i = 0;  
        while (true)  
        {  
            using (var connection = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Desktop\test.accdb"))  
            {  
                connection.Open();  
                using (var commend = new OleDbCommand("select Name form Table1", connection))  
                {  
                    var data = commend.ExecuteNonQueryAsync();  
                    Invoke((MethodInvoker)(() => textBox1.Text = (++i).ToString()));  
                }  
            }  
            await Task.Delay(100);  
      
        }  
    }  
    

    Best Regards,
    Daniel Zhang


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.