0

我之前在 Stack 上看到过几个类似的问题,但似乎没有什么适合我的需求。

我有一个简单的场景。一个流式传输 pdf 文件的网页,但一个单独的服务会每隔一段时间更新同一个 pdf 文件。我已经编写了网站和服务器,所以我可以做任何需要做的事情。

该服务实际上对临时文件做了它需要做的一切,然后在最后它替换或移动临时文件到最终的 pdf 位置。

我的想法是使用命名互斥体,但该服务会生成大量 pdf 文件,因此我不希望所有 pdf 文件都被锁定而无法读取,因为我目前正在编写特定的 pdf。我也不认为为每个 pdf 文件都有一个命名的互斥锁是不切实际的。

这似乎应该很简单。我错过了什么?有关如何控制对每个 pdf 文件的访问的建议,以便网页不会在服务尝试覆盖它的同时尝试流式传输它?日志显示这种情况每天都会发生数次。

4

2 回答 2

0

我会对 PDF 进行版本控制。

假设您有一个要流式传输的文件 FOO.PDF。它的实际名称是 FOO.1.PDF。当用户请求 FOO.PDF 时,Web 服务器获取目录中与“FOO.*.PDF”匹配的所有文件的列表,并选择编号最大的文件。

上传文件时,您上传到临时文件,然后为“FOO.*.PDF”创建一个目录,获取最高版本号,将其递增 1,然后重命名临时文件。所以下次客户想要 FOO.PDF 时,他会找到 FOO.2.PDF。

这完全消除了任何共享或锁定问题。但是,您必须不时清理目录以删除过时的版本。

于 2013-08-08T20:40:04.137 回答
0

这是我尝试过的,到目前为止它似乎工作得很好:

string mutexName = String.Format(@"Global\{0}", caseId.ToString());
Mutex mutex;
if (!Mutex.TryOpenExisting(mutexName, out mutex))
{
     bool isNew;
     MutexSecurity mSec = new MutexSecurity();
     SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
     MutexAccessRule rule = new MutexAccessRule(sid, MutexRights.FullControl, AccessControlType.Allow);

      mSec.AddAccessRule(rule);
      mutex = new Mutex(false, mutexName, out isNew, mSec);
}
if (mutex.WaitOne(5000))
{
     try
     {
          // read/write/modify the file
     }
     finally 
     {
          mutex.ReleaseMutex();
     }
}
else
{
     Common.LogInfoMessage(String.Format("Timed out waiting for pdf mutex. CaseId: {0}", caseId));
}

由于 2 个进程在不同的用户帐户下运行,我必须传入一个 MutexSecurity 对象。在这种情况下,我只是让每个人都可以访问它,但如果我想进一步限制它,我可以只让 2 个帐户访问它。另外,请确保您将名称设为全球...起初没有这样做。

打算运行几天,看看日志怎么说。不过我感觉很好。

于 2013-08-08T21:30:22.977 回答