可以使用 Control.Invoke 而不是使用锁吗?
我将拥有一个可以从多个线程以及主线程访问的数据库对象。我不希望它们同时访问底层数据库对象,因此我将编写一组可以从多个线程访问的线程安全公共方法。
我的第一个想法是在我的连接周围使用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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
听起来这似乎可行,但也听起来像是一个非常糟糕的主意。
问题是,当编写
lock
时,您会说“我希望这段代码成为关键部分”,而在编写Invoke
时,您会说“我希望执行此代码”在 UI 线程上”。这两件事当然不等同,这可能会导致很多问题。例如:Invoke
通常用于访问 UI 控件。如果开发人员看到Invoke
却没有任何与 UI 相关的内容,然后说“哎呀,这是一个不需要的Invoke
;让我们摆脱它”怎么办?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 writingInvoke
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:Invoke
is normally used to access UI controls. What if a developer seesInvoke
and nothing UI-related, and goes "gee, that's an unneededInvoke
; let's get rid of it"?我肯定会去拿锁。您通常希望 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.
为什么不尝试使用
连接池
。每个线程都可以使用不同的数据库连接完成其工作,并使用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 withInvoke
.Connection Pooling
is a very common approach used in Servers.See Using Connection Pooling with SQL Server