是否可以使用Control.Invoke而不是使用锁?

时间:2011-10-22 17:54:02

标签: c# winforms multithreading

我将拥有一个可以从多个线程以及主线程访问的数据库对象。我不希望它们同时访问底层数据库对象,因此我将编写一组可以从多个线程访问的线程安全公共方法。

我的第一个想法是在我的连接周围使用lock,例如lock(oleDbConnection),但问题是我必须为主线程锁定它,因为还有一个可以访问它的线程。这意味着要重写大量代码。

但是,由于这些线程和主线程不经常访问数据库,每次从另一个调用任何数据库方法时,如何使用我的一些控件(可能是主窗体)Invoke方法线。这样,据我所知,这些方法永远不会被同时调用,我不需要担心主线程。我想唯一的问题是性能会有所降低,但正如我所说,数据库不经常被访问;我使用线程的原因并不是它们可以同时访问数据库,但是它们可以同时执行其他操作。

这听起来像个好主意吗?我错过了什么吗?听起来有点太容易,所以我很怀疑。

3 个答案:

答案 0 :(得分:4)

听起来它会起作用AFAIK,但它听起来像是一个非常糟糕的主意

问题在于,在编写lock时,您说“我希望此代码成为关键部分”,而在编写Invoke时,您说“我希望在UI上执行此代码”线”。这两件事肯定不相同,这可能导致很多问题。例如:

  1. Invoke通常用于访问UI控件。如果开发人员看到Invoke并且没有任何与UI相关的内容,并且“哎呀,这是不需要的Invoke,那该怎么办呢?让我们摆脱它”?
  2. 如果存在多个UI线程,该怎么办?
  3. 如果数据库操作需要很长时间(或超时)怎么办?你的用户界面会停止响应。

答案 1 :(得分:3)

肯定去锁。您通常希望UI线程在执行可能需要时间的操作时响应,包括任何类型的数据库访问;你不知道它是否还活着。

此外,处理连接的典型方法是为每个请求创建,使用和处置连接,而不是重用相同的连接。这可能解决了一些并发问题。

答案 2 :(得分:1)

为什么不尝试使用Connection Pool。每个线程都可以使用不同的数据库连接进行工作,并使用Invoke将结果发送到主线程。 Connection Pooling是服务器中使用的一种非常常见的方法。

请参阅Using Connection Pooling with SQL Server