2011-10-22 31 views
3

我会有一个数据库对象,可以从多个线程以及从主线程访问。我不希望他们同时访问底层的数据库对象,所以我会编写一系列可以从多个线程访问的线程安全公共方法。可以使用Control.Invoke而不是使用锁吗?

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

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

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

回答

4

这听起来像它会工作AFAIK,但它也听起来像一个真的坏主意

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

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

我会绝对去锁。您通常希望UI线程在执行可能需要时间的操作时响应,其中包括任何类型的DB访问;例如,你不知道它是否还活着。

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

1

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

请参阅Using Connection Pooling with SQL Server

+0

如何在C#上使用连接池? – Juan

+1

您可以创建一个连接字符串,例如'Server = myAddress:myPortNumber; Database = myDataBase; UID = myUsername; PWD = myPassword; Max Pool Size = 100; Min Pool Size = 10;'然后在每个方法中创建并关闭连接。如果池中有可用的连接,您将从那里获得连接(在这种情况下不会创建新的连接,并且close将连接返回到池) –

相关问题