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

发布于 2024-12-11 18:45:43 字数 453 浏览 0 评论 0原文

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

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

但是,由于这些线程和主线程不会经常访问数据库,因此每次我从另一个线程调用任何数据库方法时,只使用我的一些控件(可能是主窗体)Invoke 方法怎么样?线。这样,据我了解,这些方法永远不会同时调用,而且我不需要担心主线程。我想唯一的问题是性能会稍微下降,但正如我所说,数据库的访问频率不高;我使用线程的原因不是为了让它们可以并发访问数据库,而是为了让它们可以并发执行其他操作。

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

I'll have a database object that can be accessed from multiple threads as well as from the main thread. I don't want them to access the underlying database object concurrently, so I'll write a set of thread safe public methods that can be accessed from multiple threads.

My first idea was to use a lock around my connection such as lock(oleDbConnection), but the problem is that I would have to lock it for the main thread since is one more thread that can access it. Which would mean rewriting lots of code.

But, since these threads and the main thread wont access the database very often, how about just using some of my control's (maybe the main form's) Invoke method every time I call any of the database methods from another thread. This way, as far as I understand, these methods would be never called concurrently, and I wouldn't need to worry about the main thread. I guess the only problem would be degrading performance a little bit, but as I said, the database is not accessed that often; the reason why I use threads is not so that they can access the database concurrently but so that they can perform other operations concurrently.

So does this sound like a good idea? Am I missing something? Sounds a bit too easy so I'm suspicious.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

初心 2024-12-18 18:45:43

听起来这似乎可行,但也听起来像是一个非常糟糕的主意

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

  1. Invoke 通常用于访问 UI 控件。如果开发人员看到 Invoke 却没有任何与 UI 相关的内容,然后说“哎呀,这是一个不需要的 Invoke;让我们摆脱它”怎么办?
  2. 如果最终存在多个 UI 线程怎么办?
  3. 如果数据库操作耗时较长(或超时)怎么办?您的 UI 将停止响应。

It sounds like it would work AFAIK, but it also sounds like a really bad idea.

The problem is that when writing lock you are saying "I want this code to be a critical section", whereas when writing Invoke you are saying "I want this to be executed on the UI thread". These two things are certainly not equivalent, which can lead to lots of problems. For example:

  1. Invoke is normally used to access UI controls. What if a developer sees Invoke and nothing UI-related, and goes "gee, that's an unneeded Invoke; let's get rid of it"?
  2. What if more than one UI thread ends up existing?
  3. What if the database operation takes a long time (or times out)? Your UI would stop responding.
无悔心 2024-12-18 18:45:43

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

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

I would definitely go for the lock. You typically want the UI thread responsive when performing operations that may take time, which includes any sort of DB access; you don't know whether it's alive or not for instance.

Also, the typical way to handle connections is to create, use and dispose the connection for each request, rather than reusing the same connection. This might perhaps solve some of your concurrency problems.

仲春光 2024-12-18 18:45:43

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

请参阅将连接池与 SQL Server 结合使用

Why don't you try to use Connection Pool. Every thread can do its work with a different DB connection and send the result to main thread with Invoke. Connection Pooling is a very common approach used in Servers.

See Using Connection Pooling with SQL Server

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文