2015-07-10 49 views
0

我做了一个在.sqlite中创建数据库的代码,所有工作都很好,但我想确保当用户第一次启动应用程序时必须完成数据库填充。如果用户中止数据库填充,则必须删除数据库(因为应用程序不使用不完整的资源)。现在,我已经使用了线程执行的是创建该数据库的方法,我已经声明了线程变量的类全球,如:Thread.Abort没有发布文件

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

Database.createDB()方法创建数据库。所有工作完美,数据库创建正确。现在我火,创建数据库,例如窗口的关闭:

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

该事件被触发正确的线程停止,但在条件启动if (File.Exists("Database.sqlite"))编译器告诉我:

灿” t删除文件 - 正在被另一个进程使用。

但我已经停止线程,为什么会出现此异常?我做错了什么?

UPDATE:

在CREATEDB()方法我也有不同类的其他方法的调用,这一个具有这样的结构:

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

我想知道在哪里应该把标志变量,因为这个代码有一个不同的循环里面。

+5

这个目的一的CancellationToken对象中止线程几乎总是错误的做法。找到一种更优雅的方式让线程知道它应该退出,然后让它干净地(例如'ManualResetEvent'或类似的) –

+0

中止“强制终止受影响的线程,即使它尚未完成其任务并且不提供清理资源的机会。” –

+1

请阅读http://stackoverflow.com/questions/9272332/what-is-a-safe-way-to-stop-a-running-thread –

回答

1

这可能是因为当你放弃线程时,它并不是干净地关闭数据库连接,因此你看到的错误。

可能我建议稍微重新设计,因为using Thread.Abort is not ideal
而是使用一个变量作为取消标志来通知线程关闭。
然后当线程检测到这个取消标志被设置时,它可以正确关闭连接并处理数据库删除本身。

更新
一个简单的例子来说明我的意思;它不漂亮,它不会编译,但它提供了一般的想法。

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

而现在,你知道你要找大致什么,因为我衷心建议谷歌搜索的,谁知道他们在谈论什么人线程取消的职位可以告诉你怎么做是正确的。

这些可能是合理的出发点:
How to: Create and Terminate Threads
.NET 4.0+实际上已经在考虑Cancellation in Managed Threads

+3

“不理想”时应该被授予“年度委婉语”奖励的代码部分... –

+0

有点问题是我有CreateDb()中的其他类的不同类的方法;这种方法有一个foreach ..我应该把这个条件“停止”在foreach? –

+0

可能是的。如果你编辑你的问题并添加一些CreateDb()代码,这将更容易说出来。 – Nanhydrin