当另一个线程/进程使用独占锁时,是否可以绕过C#中的文件锁?

有没有办法绕过或删除另一个线程持有的文件锁而不杀死线程?

我在我的应用程序中使用第三方库,该库对文件执行只读操作。 我需要第二个线程同时读取该文件以提取第三方库未公开的一些额外数据。 不幸的是,第三方库使用读/写锁打开文件,因此我得到通常的“进程无法访问文件…因为它正被另一个进程使用”exception。

我想避免使用我的线程预加载整个文件,因为文件很大并且会导致加载此文件和超出内存使用量的不必要的延迟。 由于文件的大小,复制文件是不实际的。 在正常操作期间,两个线程命中同一文件不会导致任何重大的IO争用/性能问题。 我不需要在两个线程之间进行完美的时间同步,但是它们需要在相隔半秒的时间内读取相同的数据。

我无法更改第三方库。

有没有解决这个问题的方法?

如果您开始搞乱底层文件句柄,您可能能够解锁部分,问题是访问该文件的线程不是为处理这种篡改而设计的,可能最终崩溃。

我强烈建议修补第三方图书馆,你做的任何事情都可能,并且可能会在现实条件下爆炸。

简而言之,您无法对第三方锁定文件做任何事情。 您可以通过上面提到的Richard E的答案来解决实用程序Unlocker。

一旦第三方打开文件并对其设置锁定,底层系统将为该第三方提供锁定,以确保没有其他进程可以访问它。 对此有两种思路。

  • 使用DLL注入来修补代码以显式设置锁定或取消设置锁定。 这可能是危险的,因为你会弄乱另一个进程的稳定性,并可能最终导致进程崩溃并导致悲痛。 想想看,底层系统跟踪进程打开的文件……当时注入DLL并修补代码 – 这需要技术知识来确定您希望在运行时注入哪个进程并更改标志截取Win32 API时调用OpenFile(...)
  • 由于这被标记为.NET,为什么不将第三方的源代码转换为.il文件,并将锁的标志更改为共享,通过将所有.il文件重新编译回DLL来重建库。 当然,这需要根据某些类别在某个类中发生文件打开的代码。

看看这里的播客。 在这里看一下,解释如何在此处突出显示上面突出显示的第二个选项。

希望这会有所帮助,最好的问候,汤姆。

这并不能直接解决您的情况,但是像Unlocker这样的工具可以通过Windows用户界面来实现您的目标。

任何低级别的黑客攻击都可能导致线程崩溃,文件损坏等。

因此,我认为我会提到下一个最好的事情,只需轮到你轮流直到文件没有被锁定: https : //stackoverflow.com/a/11060322/495455


我不认为这第二个建议会有所帮助,但最接近的事情(我知道)将是DemandReadFileIO :

 IntSecurity.DemandReadFileIO(filename); internal static void DemandReadFileIO(string fileName) { string full = fileName; full = UnsafeGetFullPath(fileName); new FileIOPermission(FileIOPermissionAccess.Read, full).Demand(); } 

我认为这是一个可以用c ++解决的问题。 这烦人,但至少它是有效的(如下所述: win32 C / C ++从“锁定”文件中读取数据 )

步骤是:

  1. 使用fsopen和_SH_DENYNO标志在第三个库之前打开文件
  2. 使用第三个库打开文件
  3. 阅读代码中的文件

您可能也对这些链接感兴趣:

  1. 从c#调用c ++( 可以从C#调用C ++代码? )
  2. 这篇文章的内部链接带有一个样本( http://blogs.msdn.com/b/borisj/archive/2006/09/28/769708.aspx

您是否尝试在第三方库获取它之前制作文件的虚拟副本…然后使用实际副本进行操作,从逻辑上讲,只有在我们讨论的文件相当小时才会考虑这一点。 但这是一种骗子:)祝你好运

如果文件被锁定且未被使用,那么您的文件锁定/解锁机制的工作方式就会出现问题。 您只应在修改文件时锁定文件,然后立即将其解锁以避免这种情况。