简体   繁体   中英

Thread.Abort doesn't release a file

I made a code that create a Database in .sqlite, all working good but I want to be sure that when the user start for the first time the application the Database population must be completed. If the user abort the database population, the database must be deleted (because the application don't working with an incomplete resource). Now I've used the thread for execute the method that create this Database, and I've declared the thread variable global in the class, like:

Thread t = new Thread(() => Database.createDB());

The Database.createDB() method create the DB. All working perfect, the DB is created correctly. Now I fire the closing of the window that creating the DB like:

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
    {
            MessageBoxResult result = MessageBox.Show(
                    @"Sure?",
                    "Attention", MessageBoxButton.YesNo, MessageBoxImage.Question);
            try
            {
                if (result == MessageBoxResult.Yes)
                {
                    t.Abort();

                    if (File.Exists("Database.sqlite"))
                    {
                        File.Delete("SoccerForecast.sqlite");
                        Process.GetCurrentProcess().Kill();
                    } ....

The event was fired correct and the thread stopped, but when the condition start if (File.Exists("Database.sqlite")) the compiler tell me:

Can't delete file - in using by another process.

But I've stopped the thread, why this exception appear? What I doing wrong?

UPDATE:

In CreateDb() method I also have a call to other method of different class, one of this have the structure like this:

public void setSoccer()
{
        Database.m_dbConnection.Open(); 
        string requestUrl = "...";
        string responseText = Parser.Request(requestUrl);
        List<SoccerSeason.RootObject> obj = JsonConvert.DeserializeObject<List<SoccerSeason.RootObject>>(responseText);

        foreach (var championships in obj)
        {
            string sql = "string content";
            SQLiteCommand command = new SQLiteCommand(sql, Database.m_dbConnection);
            try
            {
                command.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        string query = "select * from SoccerSeason";
        SQLiteCommand input = new SQLiteCommand(query, Database.m_dbConnection);
        SQLiteDataReader reader = input.ExecuteReader();

        int i = 0;
        while (reader.Read())
        {
            //reading data previously inserted in the database
        }
        Database.m_dbConnection.Close(); /
}

I was wondering where I should put the flag variable because this code have a different loop inside.

It could be that when you're aborting the thread it's not cleanly closing the database connections, hence the error you're seeing.

Might I suggest a slight redesign because using Thread.Abort is not ideal .
Instead use a variable as a cancel flag to notify the thread to shut down.
Then when the thread detects that this cancel flag is set it can properly close connections and handle the database delete itself.

Update :
A brief example to illustrate what I mean; it ain't pretty and it won't compile but it gives the general idea.

public class Database
{
    public volatile bool Stop= false;

    public void CreateDb()
    {
        if(!Stop)
        {
           // Create database 
        }

        if(!Stop)
        {
           // Open database
           // Do stuff with database
        }

        // blah blah ...

        if(Stop)
        {
           // Close your connections
           // Delete your database
        }
    }
}

...

    protected override void OnClosing(CancelEventArgs e)
    {
        Database.Stop = true;
    }

And now that you know roughly what you're looking for I heartily recommend Googling for posts on thread cancellation by people who know what they're talking about that can tell you how to do it right.

These might be reasonable starting points:
How to: Create and Terminate Threads
.NET 4.0+ actually has a CancellationToken object with this very purpose in mind Cancellation in Managed Threads

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM