我有一个类,ProcessorClass。它有两个方法Start()和Stop()。当你点击开始时,它会在内部创建一堆线程进行一些处理,如果他们发现相关内容,就会触发一个事件。
我的表单frmMain(这是一个Windows窗体应用程序.net 3.5)有一个这个类的实例,正在捕获这些事件。每次捕获事件时,都会将某些内容插入到数据库中。我是否正确地得出结论,这种策略将确保同步插入?我不能让多个线程尝试进行数据操作,因为这会导致我丢失数据。
答案 0 :(得分:1)
此策略不确保一切都在一个线程上发生。事件在触发它们的线程上处理。你应该使用一个静态lockobject并锁定它(lock(lockobject){...})
P.S。为什么插入数据库的多个线程会导致数据丢失?什么数据库?
答案 1 :(得分:1)
锁定您想要互相排斥的代码部分。
public void InsertIntoDataBase()
{
lock(
// Insert something into database.
)
}
对InsertIntoDataBase函数的任何请求都将排队,直到删除锁定为止,并按照它们到达的顺序执行代码。
答案 2 :(得分:1)
不,这些不是同步插入,特别是在多核机器上。我建议将并发处理放在数据库更新中,而不是回到单线程或锁定内存中的某个对象。通过使用WHERE子句检查执行更新的同一语句上的旧值,可以在数据库中没有锁的情况下执行此操作。如果结果插入了零行,则并发检查可以使您免于数据损坏。
但是,如果您没有适用于业务规则的重试机制,则需要将并发规范添加到数据库事务中。 (即,打开一个事务,将它附加到您的命令,并将事务并发级别设置为您需要的安全级别。)
答案 3 :(得分:1)
假设这些事件是同步触发的,处理程序将触发生成器线程。这是否会导致竞争条件取决于底层数据库。
如果必须确保不发生并行插入,则可以使用lock {}关键字进行同步。
我不确定为什么数据库插入的处理程序驻留在表单子类中,但鉴于它确实如此,BeginInvoke(即Control.BeginInvoke)也可以用于同步。然而,这是不好的做法。