0

I use SQLITE and I want to be able to regularly check the status of the database to display icon on the UI.

As the database will be on a remote share (another computer or a server), I need to be able to perform this check without freezing the application for a minute because the remote host is not reachable.

For that I use the following code:

        public bool Connexion_Possible()
        {
            bool possible = false;

            DateTime start_time = DateTime.Now;
           

            Thread t = new Thread
            (

                new ThreadStart(delegate ()
                {

                    SQLiteConnection sqlite_conn;

                    sqlite_conn = new SQLiteConnection("Data Source=" + Localisation_BDD() + ";Version=3;FailIfMissing=True;Pooling=False;");



                    try
                    {
                        sqlite_conn.Open();
                        possible = (sqlite_conn.State == ConnectionState.Open);
                        sqlite_conn.Close();
                    }
                    catch(Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Erreur thread", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                    finally
                    {
                        sqlite_conn.Dispose();
                    }

                })

            );
            t.Start();

            bool completed = t.Join(500);

            MessageBox.Show("Joined after : " + (DateTime.Now - start_time).TotalMilliseconds.ToString("N0"), "", MessageBoxButton.OK, MessageBoxImage.Error);

            if (!completed) {t.Interrupt(); t.Abort(); }

            MessageBox.Show("Aborted after : " + (DateTime.Now - start_time).TotalMilliseconds.ToString("N0"), "", MessageBoxButton.OK, MessageBoxImage.Error);

            return possible;
        }

The problem is that the application is frozen for about twenty seconds, it is much longer than the 500ms planned...

MessageBoxs displayed :

Joined after : 496

Aborted after : 20 538

Erreur thread = unable to open database file.

The inability to join the database is normal because I am trying to manage this case.

My problem is : why do I have 20 seconds between the joining and the abortion of the thread?

UserNam3
  • 655
  • 4
  • 11
  • 2
    Please read the documentation on Thread.Abort, and do what it says: i.e. don't use Thread.Abort. – Ian Kemp Nov 13 '20 at 10:55
  • I use a modified code that I get from https://stackoverflow.com/questions/1232953/speed-up-file-exists-for-non-existing-network-shares What can I do if abort is not possible ? – UserNam3 Nov 13 '20 at 10:57
  • 2
    All that this check achieves is to tell you that something was/wasn't possible in the recent past. It does nothing to tell you *what is possible at the present time*, because networks and remote servers can add/lose connectivity spontaneously, etc. Far better to just have the actual code that tries to work with the database to report issues *when they occur*. You have to write such code anyway (because, see above, you don't know they'll succeed until you actual run them) – Damien_The_Unbeliever Nov 13 '20 at 11:07
  • I agree, the purpose of this code is to update an icon indicating the status of the database. And by exentension, the handling of the application freeze problem will be the same for the database queries. – UserNam3 Nov 13 '20 at 11:31
  • 1
    Sqlite was written in the C language. Unmanaged code is not abortable while it is running. Only other thing you can do is run another process with the Process class. Use its Kill() method. The isolation between processes that the OS provides makes that safe. – Hans Passant Nov 13 '20 at 11:31
  • Using another process is not heavier for this little function ? – UserNam3 Nov 13 '20 at 11:40
  • What is the reasoning behind the desire to abort the background thread? – Theodor Zoulias Nov 13 '20 at 12:19
  • When the program tries to access the database on a remote server that is no longer accessible, the whole program freezes for almost a minute. It's like your Windows, when you try to open a shared folder in an unaviable host. I want to try to acces, if after x seconds there is no result, it's probably because the server is no longer accessible. – UserNam3 Nov 13 '20 at 13:17
  • 2
    Careful with the MessageBox.Show() call inside the new thread's body - you're not supposed to touch the UI from another thread other than the main thread. – BlueStrat Nov 13 '20 at 17:58
  • I remove it soon. By the way, I still have the problem :( – UserNam3 Nov 13 '20 at 17:59
  • A blocked background thread shouldn't cause freezing of the UI. Something else is going on. Instead of searching how to abort the background thread, you should probably search for the hidden interaction between that thread and the UI thread. Or for the common cause that causes both threads to get stuck. – Theodor Zoulias Nov 13 '20 at 19:14
  • I tried commenting out the code instruction by instruction. The freeze is caused by .abort() if it is not threaded. If it is, the freeze come with .abort() – UserNam3 Nov 13 '20 at 19:23
  • If the `Abort` is the problem then the solution is simple: remove the `Abort`. It is considered [bad practice](https://stackoverflow.com/questions/1559255/whats-wrong-with-using-thread-abort) anyway, and on .NET Core it's not even supported. – Theodor Zoulias Nov 14 '20 at 09:31
  • I thought about it, but doesn't that mean that the thread is going to be orphan? If I do multiple checks in a short period of time, isn't that a problem? – UserNam3 Nov 14 '20 at 11:25
  • @UserNam3 - What do you mean by an "orphan"? What is the problem with multiple checks over a short period? – Enigmativity Nov 16 '20 at 04:47
  • When the Connection_possible function is finished, nothing will refer to the thread created inside. So this one will continue to exist without any way to interact with it. This is what I mean by orphan thread. If I close the app right after checking the connection, will there still be an orphaned thread that will prevent it from closing until it has finished processing on its own? Doing several successive checks would increase the number of orphaned threads, I think. I'm sorry, I'm new to thread management. – UserNam3 Nov 16 '20 at 08:12

1 Answers1

-2

try to use Task instead of Thread and then use async method to perform that task

private async Task myTask()
{
       //codes
} 

then in the calling method do

private async void mainMethod()
{
  await myTask();
}