我主要在后台线程中使用FireDAC,偶尔在主GUI线程中使用。
根据文档,有4种可能的执行模式,在我看来,只有2种是合适的。
amBlocking调用线程和GUI被阻止,直到操作完成。
这是默认值,似乎工作正常。尽管我不满意它说“并且GUI被阻止”-我不需要在后台线程完成工作的同时阻止GUI。这种破坏了线程的目的。它还可能导致非显而易见的死锁。
amNonBlocking调用线程被阻塞,直到操作完成为止。 GUI没有被阻止。
此模式似乎更合适,因为它仅阻止调用线程,这似乎是我所需要的。但实际上,并非如此。呼叫有时会失败,但有例外
EFDException [FireDAC] [Phys] [SQLite] -326。无法执行该操作,因为上一个操作正在进行中。
所有线程上对FireDAC的所有调用都以关键部分序列化-根据文档,这对于FireDAC的线程安全操作就足够了。在发布关键部分之前,所有数据集/查询均已关闭。
主要问题是,选择哪种执行模式?子问题是-它是否是FireDAC中的错误,并且amNonBlocking已损坏?
如果任何人有相同的问题,解决方案如下,在对数据库进行任何操作之前,请致电:
if GetCurrentThreadId = MainThreadID then
FDConn.ResourceOptions.CmdExecMode := amBlocking
else
FDConn.ResourceOptions.CmdExecMode := amNonBlocking;