0

我们有一个不受我们控制的大型电子商务应用服务器,我们不能以任何方式修改它的形状或形式。该应用服务器背后的公司也不会根据客户的要求对其进行修改。这是因为他们将我们视为竞争对手,并且他们不希望客户将我们的应用程序用作其应用程序的前端。

我们的桌面应用程序使用 Web 服务与该应用程序服务器进行通信,并且每次从桌面登录都占用服务器上的一个用户槽。应用程序服务器不提供使我们能够确定用户槽是否被占用的功能。最好的解决方案是我们开发一个位于应用服务器和桌面客户端中间的应用程序,该应用程序将管理用户槽的分配和解除分配,问题就解决了。此解决方案已被拒绝,因为客户不想在电子商务应用程序服务器上安装我们的应用程序,因为这会使用户对所述电子商务服务器的支持无效,替代方案将是额外的服务器,但这是他们不这样做的。不想处理。

这给我们留下了我们的桌面应用程序对共享文件夹具有写入权限的解决方案。每个桌面应用程序都有一个 UID,我们将该 UID 与用户槽 id 一起使用,并创建一个文件 UID.UserSlotId.locked。这意味着每次建立连接时,桌面应用程序都需要检查此共享位置,并确保它们不会使用已获取的 UserSlotId。

现在我知道锁定文件是一个糟糕的解决方案,但客户已经提出了这个要求,无论我们如何告知他们这永远不会是一个防水的解决方案,他们仍然希望继续进行。他们假设 98% 的解决方案是一个好的解决方案。那么 StackOverflow 社区在处理这种文件锁定系统时可以提供什么建议呢?

4

1 回答 1

0

以写入模式打开锁定文件,并在应用程序使用插槽时保持打开状态。

private static void TakeFistUnusedLock(FileStream[] currentLock)
{
    for (int i = 1; i < 5; i++)
    {
        try
        {
            var fs = File.OpenWrite(Path.Combine(Path.GetTempPath(), "DbLock", i.ToString() + ".lock"));
            currentLock[i - 1] = fs;
            Console.WriteLine("Got lock " + i);
            break;
        }
        catch (Exception) { }
    }
}

我这样测试

FileStream[] currentLock = new FileStream[5];
var path = Path.Combine(Path.GetTempPath(), "DbLock");
DirectoryInfo di = new DirectoryInfo(path);
di.Create();


TakeFistUnusedLock(currentLock);
TakeFistUnusedLock(currentLock);
TakeFistUnusedLock(currentLock);

currentLock[1].Dispose(); // release lock 2

TakeFistUnusedLock(currentLock);

输出是

Got lock 1
A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
Got lock 2
A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
Got lock 3
A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
Got lock 2

无需保留 currentLock 数组,您只需为每个应用程序存储一个锁。您需要存储打开的 FileStream 以确保文件在写入模式下保持打开状态。要释放锁,您释放存储的 FileStream,然后释放文件上的写锁。
此方法可确保即使您的应用程序崩溃也能释放锁。

于 2011-02-10T21:22:19.030 回答