Tag: locking

需要击败GC并且一旦超出范围就将对象销毁

我需要使用Mutex保护几段代码。 问题是代码看起来像这样: lock(mylockobject) { if(!foo()) throw new MyException(“foo failed”); if(!bar()) throw new MyException(“bar failed”); } 使用锁,它可以按照我的意愿工作,但现在我需要使用互斥锁。 这里显而易见的问题是,如果我获取互斥锁并且foo()或bar()失败,我将不得不在抛出每个exception之前释放互斥锁。 在C ++中,我将利用在堆栈上创建的对象的范围,并将互斥锁定在对象的构造函数中,然后在析构函数中释放它。 使用.NET的垃圾收集,我认为这不会起作用。 我写了一个测试应用程序,并确认如果我做这样的事情: public class AutoMutex { private Mutex _mutex; public AutoMutex(Mutex mutex) { _mutex = mutex; _mutex.WaitOne(); } ~AutoMutex() { _mutex.ReleaseMutex(); } } 然后有这样的代码: // some code here… Mutex my_mutex = new Mutex(false, “MyMutex”); { // […]

multithreading应用程序中SQLite“数据库已锁定”错误

有一个multithreading应用程序,适用于大型DB文件(> 600 Mb)。 当我添加blob数据时,“数据库被锁定”问题就开始了,并且每个请求开始运行> 30 Kb的BLOB数据。 我认为问题与小硬盘速度有关。 它看起来像SQLite删除-journal文件,我的应用程序的一个线程失控(因为-journal文件被应用和删除),而其他我的线程想要与数据库做smth,但SQLite仍然更新DB文件…当然,每次数据库调用后我都可以做一分钟延迟,但这不是解决方案,因为我需要更快的速度。 现在我使用每个会话(每个线程)实现的会话。 因此每个应用程序对象和许多ISession对象都有一个ISessionFactory。 有我的助手类(你可以看到我使用IsolationLevel.Serializable和CurrentSessionContext = ThreadStaticSessionContext): public abstract class nHibernateHelper { private static FluentConfiguration _configuration; private static IPersistenceContext _persistenceContext; static nHibernateHelper() {} private static FluentConfiguration ConfigurePersistenceLayer() { return Fluently.Configure().Database(FluentNHibernate.Cfg.Db.SQLiteConfiguration.Standard.ShowSql().UsingFile(_fileName).IsolationLevel(IsolationLevel.Serializable).MaxFetchDepth(2)). Mappings(m => m.FluentMappings.AddFromAssemblyOf()).CurrentSessionContext(typeof(ThreadStaticSessionContext).FullName); } public static ISession CurrentSession { get { return _persistenceContext.CurrentSession; } } public static IDisposable OpenConnection() […]

如何在不锁定数据库的情况下使用数据读取器执行SQLite查询

我使用System.Data.Sqlite来访问C#中的SQLite数据库。 我有一个查询必须读取表中的行。 在遍历行并且在阅读器打开时,必须执行某些SQL更新。 我遇到了“数据库被锁定”的exception。 SQLite文档说明: 当进程想要从数据库文件中读取时,它遵循以下步骤: 打开数据库文件并获取SHARED锁。 该文档进一步说明了“共享”锁定: 可以读取数据库但不写入。 任意数量的进程可以同时保存SHARED锁,因此可以有许多同时读取器。 但是,当一个或多个SHARED锁处于活动状态时,不允许其他线程或进程写入数据库文件。 FAQ说明: 多个进程可以同时打开同一个数据库。 多个进程可以同时执行SELECT。 但是,只有一个进程可以随时对数据库进行更改。 SQLite权威指南一书指出: …通过使用read_uncommited编译指示,连接可以选择具有读取未提交的隔离级别。 如果将其设置为true ,则连接将不会在其读取的表上放置读锁定。 因此,另一个writer实际上可以更改表,因为read-uncommitted模式下的连接既不会阻塞也不会被任何其他连接阻塞。 我尝试将pragma设置为在SQL查询命令语句中读取未提交,如下所示: PRAGMA read_uncommitted = 1; SELECT Column1, Column2 FROM MyTable 使用不同连接的同一线程上的SQL更新仍然失败,并出现“数据库已锁定”exception。 然后,我尝试将隔离级别设置为在连接实例上读取未提交。 同样的例外仍然没有变化。 如何在不锁定数据库的情况下使用开放数据读取器来遍历数据库中的行,以便我可以执行更新? 更新: 以下两个答案都有效。 然而,我已经从使用默认回滚日志转移到现在使用预写日志,这提供了改进的数据库读写并发性。

通过System.Data.SQLite和c#多次访问单个SQLite数据库文件

正如我可以从SQLite FAQ中读到的,它支持多个进程读取(SELECT),并且在任何时刻都只支持一个进程编写(INSERT,UPDATE,DELETE)数据库: SQLite使用读取器/写入器锁来控制对数据库的访问。 当任何进程想要写入时,它必须在更新期间锁定整个数据库文件。 但这通常只需要几毫秒。 其他流程只是等待作者完成然后继续他们的业务 我通过c#使用System.Data.SQLite适配器。 有人可以告诉我PLZ,这个过程到底是怎么回事? 这个过程是否会自动运行,编写SQLiteCommand只会等待另一个SQLiteCommand已经在同一个数据库上执行? 或者它可能会抛出exception? 什么样的? 对不起,我发现没有关于这个机制的信息:) 谢谢。 更新: 我发现post说exception会引发一个特定的错误代码 这个陈述是否正确?

SqlConnection / SqlCommand线程安全吗?

我目前正在创建一个WCF Web服务。 作为其工作的一部分,遗憾的是需要进行一些相当密集的计算,但幸运的是,这些计算可以在对Web服务的调用之间共享。 实际上 – 我们只需要进行一次计算,所有后来的调用都可以获得好处。 但是,由于WCF没有共享应用程序状态,因此在单实例模式下设置WCF似乎是合乎逻辑的。 (每个客户端都需要进行一些计算,迫使我们重新计算它们,这可能是正常的,或者每次调用都是站不住脚的,这是不可能的) 但是,我不太熟悉保护multithreading的代码。 我一直在阅读它,因为我们的WCF代码都没有写入共享状态(除了计算位,这很容易保护)我几乎确信我不需要改变任何东西。 但是有一个障碍 – 我们使用SqlConnection和SqlCommand与我们的后端进行通信,我不确定我是否可以指望这些是线程安全的? 编辑:我应该澄清命令/连接始终是方法的本地。 我们正在谈论一种模式: using sqlConn = new SqlConnection(…) { try { sqlConn.Open() } catch () { throw new FaultException(); } var cmd = new SqlCommand(“Some SQL”, sqlConn); var reader = cmd.ExecuteReader(); //Read the stuff reader.Close(); //Return something } 结束编辑 我在MSDN上查找了SqlCommand类: http : //msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.aspx其中说:“任何公共静态(在Visual […]

如何正确执行Parallel.ForEach,锁定和进度报告

我正在尝试实现Parallel.ForEach模式并跟踪进度,但我遗漏了一些关于锁定的内容。 以下示例在threadCount = 1时计数为1000,但在threadCount > 1时不threadCount 。正确的方法是什么? class Program { static void Main() { var progress = new Progress(); var ids = Enumerable.Range(1, 10000); var threadCount = 2; Parallel.ForEach(ids, new ParallelOptions { MaxDegreeOfParallelism = threadCount }, id => { progress.CurrentCount++; }); Console.WriteLine(“Threads: {0}, Count: {1}”, threadCount, progress.CurrentCount); Console.ReadKey(); } } internal class Progress { private […]