【发布时间】:2010-04-22 11:00:03
【问题描述】:
我目前正在开发一个文件处理服务,它查看文件共享,文件通过 FTP 上传到该文件。
为了可扩展性,我被要求使该服务能够进行负载平衡,因此该服务必须预期不同机器上的其他服务也可能会尝试处理这些文件。
好的,所以我认为我应该能够通过在处理文件之前为我的进程获取排他锁并跳过可能已经被另一个进程锁定的任何文件来实现这一点。
这种方法的关键如下所示(为简单起见,我省略了错误处理):
using(FileStream fs = File.Open(myFile, FileMode.Open, FileAccess.ReadWrite, (FileShare.Read | FileShare.Delete))
{
//Do work
}
Q1:我的进程现在锁定了这个文件。我认为这意味着我可以访问同一个文件(不使用流)并且仍然可以正确访问它,但是根据测试,我似乎只有通过流锁定的好处。这是正确的吗?
(例如,在我包含 FileShare.Delete 之前,File.Delete(myFile) 失败)
上述锁最终使用'Write'权限来确定哪个服务拥有该文件,但旨在允许其他进程仍然读取该文件。这是因为拥有锁的进程会尝试验证文件是否为有效的 zip 文件,该文件使用第三方库 (Xceed.Zip)。然而,这失败了,说文件“正在被另一个进程使用”。使用反射器我最终发现有问题的调用是:
stream = this.m_info.Open(FileMode.Open, FileAccess.Read, FileShare.Read);
现在我希望它能够工作,因为它只想读取文件,但它失败了。原因似乎在similar question 中进行了概述。但是,由于这是第 3 方 API,我无法更改他们的代码以使用 ReadWrite。
Q2:有没有办法可以正确锁定文件,使其不会被其他服务获取,但仍可以使用外部 API 将其验证为 zip 文件?
我觉得应该有一个“正确”的方法来做到这一点,但目前我能想到的最好办法是锁定文件,将其移出共享目录,然后在新的位置。
【问题讨论】:
标签: file windows-services concurrency locking