使用线程进行数据库操作的最佳方法是什么?

时间:2013-05-08 22:08:03

标签: c# sql windows multithreading forms

我正在使用SQL Compact作为主数据库开发WinForms应用程序。我被告知我永远不会弄乱UI线程,每个操作都需要在UI线程之外完成..每个CRUD操作的演讲我创建一个线程并出现一个进度条,但我想这可能不是这样做的最佳方法,我不确定在何时何地使用线程与数据库操作一起使用。我没有使用UI线程来进行这些数据库调用,但如果我愿意,我没有看到任何问题。为了向用户显示信息,我在需要时进行调用(在网格或组合框上显示数据)。这是一小段代码:

this.SuspendLayout();

                ProgressDialog progressDialog = new ProgressDialog();


                Thread backgroundThread = new Thread(
                    new ThreadStart(() =>
                    {
                        var unitOfWork = new DAL.Implementations.Entity_Framework.UnitOfWork<dbgmEntities>();
                        var espacosRepository = unitOfWork.GetRepository<DAL.Espacos>();
                        Espacos espaco;

                        if (e.Row.Cells["ESP_Descr"].Value != null)
                            espaco = new Espacos { ESP_Nome = e.Row.Cells["ESP_Nome"].Value.ToString(), ESP_Descr = e.Row.Cells["ESP_Descr"].Value.ToString() };

                        else
                            espaco = new Espacos { ESP_Nome = e.Row.Cells["ESP_Nome"].Value.ToString() };


                        espacosRepository.AddOrAttach(espaco);
                        unitOfWork.Save();

                    }
              ));


                backgroundThread.Start();
                progressDialog.Show();
                progressDialog.Close();
                this.ResumeLayout();

我正在使用Repository Pattern和SQL Compact和Entity Framework 4.0,因为你可以看到我在线程内部进行数据库操作而不是UI线程,如果它是一个繁重的操作,它会阻塞用户界面..问题是:

是否真的有必要从UI线程之外的线程进行数据库调用,或者只是一个繁重的操作?就像在不同的表上添加超过1或2行一样。

由于

2 个答案:

答案 0 :(得分:3)

UI线程实际上应该只用于向用户显示内容并处理来自用户的输入事件。应该将任何其他内容分配给工作线程。这包括数据库操作。问题是长时间运行的进程会占用主线程,因此在进程持续时间内无法执行任何其他操作。由于很难保证您的数据库操作能够快速恢复,因此在主线程上访问它的操作可能不是一个好主意。

请记住,这只是一个指导原则。如果您正在执行的任何工作只需要很短的时间,那么启动一个新线程是不值得的。启动一个新线程也会花费你的CPU周期,因此在另一个线程上完成这项工作可能不值得。

一些建议:

  • 不要直接实例化线程;请改用线程池:ThreadPool.QueueUserWorkItem
  • 不要立即关闭进度条。显示它,然后在数据库操作完成后调用该调用将其隐藏在工作线程中。

This is a good article on the thread pool.

答案 1 :(得分:0)

正如Dan所说,UI线程应该仅用于显示内容和获取用户输入。

然而,我们倾向于做的绝大多数操作非常快。与简单地执行操作本身相比,启动另一个线程会增加时间成本。我的建议是你只需要一个新的线程来处理任何需要花费几秒钟才能处理的东西。