C# - 锁定文件,直到浏览器关闭、用户离开页面或会话过期

发布于 2024-08-14 04:55:09 字数 297 浏览 12 评论 0原文

有没有办法锁定文件,直到浏览器关闭、用户离开当前页面或会话过期?

我有一个java应用程序,它从文本文件读取注释,并允许用户通过java应用程序修改或添加更多注释到pdf。一旦完成,他们单击“保存”,完整的注释文件将返回到其原始数据文件。

问题是两个人可以打开相同的注释文件并执行不同的更新。然后,当每次保存时,它们都会覆盖现有文件,以便仅保存第二个用户的更改。

理想的解决方案是让 1 个人“签出”文件进行编辑,进行修改,直到他们关闭窗口、离开页面或会话过期,然后文件将自动“签入”。有什么方法可以在 C# 中做到这一点吗?谢谢!

Is there any way to lock a file until a browser is closed, the user leaves the current page, or their session expires?

I have a java app that reads annotations from a text file and lets a user modify or add more annotations to a pdf through the java app. Once they do, they click 'save' and the full annotation file is returned to it's original data file.

The issue is that 2 people can open the same annotation file and perform different updates. Then, when each saves, they overwrite the existing file so that only the 2nd user's changes are saved.

The ideal solution is to let 1 person 'check-out' the file for edit, make their modifications until either they close the window, navigate away from the page, or their session expires, then the file would automatically 'check-in'. Any way of doing this in C#? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

何必那么矫情 2024-08-21 04:55:10

好吧,没有简单的内置方法可以做到这一点,您可以做的是在与注释文件夹相同的文件夹中创建一个 {username}.lock 文件。然后在读取或保存之前检查目录中是否有 .lock 文件。

如果有文件告诉用户它已被锁定并且无法更新。显然,您需要确保删除 .lock 文件,否则在第一次访问后没有人能够访问注释文件。

Well is there is no simple built in way to do this , what you can do is create a {username}.lock file in the same folder as the annotations folder. Then before you read or save check if there is a .lock file in the directory.

If there is a file tell the user its been locked and can not be updated. Obviously you need to make sure that you delete the .lock file otherwise after first access no one will ever be able to access the annotations file.

手长情犹 2024-08-21 04:55:10

如果两个用户能够编辑是应用程序的工作方式,那么为每个用户获取文件的临时副本进行编辑不是更有意义吗?

If two users being able to edit is the way the app works, does it not maybe make more sense to take a temporary copy of the file per user for editing?

话少情深 2024-08-21 04:55:10

您可以将锁定代码放在 Global.asax 文件的 Session_Start 中,将释放代码放在 Session_End 方法中。然而,尝试确定用户何时真正离开会话以便在不等待会话超时的情况下触发这些事件很难检测到,但可以通过 AJAX 和一些 Javascript 来完成。

示例

protected void Application_Start()
{
    Application("AnnotationFileLocked") = False;
}
...

protected void Session_End()
{
    if ((bool)Application("AnnotationFileLocked"))
    {
         // Session("UserName") could be set on Login
         if ((string)Application("AnnotationFileLockedBy") == (string)Session("UserName"))
         {
             Application("AnnotationFileLocked") = False;
             Application.Remove("AnnotationFileLockedBy");
         }
    }
}

然后在代码中的任何位置检出该文件:

public void CheckOutFile()
{
    if (!(bool)Application("AnnotationFileLocked"))
    {
        Application("AnnotationFileLocked") = True
        Application("AnnotationFileLockedBy") = (string)Session("UserName");
        // do stuff
    }
}

You could put your lock code in the Session_Start and your release code in the Session_End methods of the Global.asax file. However, trying to determine when the user has really left the session in order to trigger these events without waiting on the Session timeout is difficult to detect but it can be done via AJAX and some Javascript.

Example

protected void Application_Start()
{
    Application("AnnotationFileLocked") = False;
}
...

protected void Session_End()
{
    if ((bool)Application("AnnotationFileLocked"))
    {
         // Session("UserName") could be set on Login
         if ((string)Application("AnnotationFileLockedBy") == (string)Session("UserName"))
         {
             Application("AnnotationFileLocked") = False;
             Application.Remove("AnnotationFileLockedBy");
         }
    }
}

Then wherever in your code you check out the file:

public void CheckOutFile()
{
    if (!(bool)Application("AnnotationFileLocked"))
    {
        Application("AnnotationFileLocked") = True
        Application("AnnotationFileLockedBy") = (string)Session("UserName");
        // do stuff
    }
}
乖不如嘢 2024-08-21 04:55:10

这样的锁确实没有什么好的办法。尽管您可以将代码放入 Session_End 中来清理锁,但不能保证触发该事件。例如,服务器可能在会话期间崩溃。您将留下一个永久锁定的文件。

由于您想要简单性,因此您可以考虑使用基于超时的锁定。当用户 A 开始编辑文件时,他们将获得 60 分钟(或您选择的任何时间段)的独占访问权限。您在数据存储中添加了一个条目,表示最近的编辑锁定针对用户 A,并于中午 12:42 到期。用户 A 可以在这段时间内随意编辑。如果他之前完成了,他可以单击“完成”按钮来删除锁定条目。您甚至可以给他一个“更多时间”按钮,将锁定到期时间戳更新为从现在起 60 分钟。

如果用户 B 出现并尝试编辑该文件,您的应用程序会检查列表并发现该文件在今天中午 12:42 之前被锁定。如果用户 A 离开并且从未完成,或者保存并忘记解锁,或者应用程序崩溃,您无需担心解锁或清理。用户 B 只需等到 12:42 左右,然后您的应用程序将忽略现有的锁定条目,因为它已过期。

很多 wiki 都使用与此类似的方法。它可能并不完美,但是用户很容易理解,并且不需要任何操作员维护。

There is really no good way to do locks like that. Though you can put code into Session_End to clean up the locks, that event is not guaranteed to fire. For instance, the server might crash during a session. You'd be left with a permanently locked file.

Since you want simplicity, you might consider using timeout-based locking. When user A starts editing the file, they get exclusive access to it for 60 minutes (or whatever span you choose). You put an entry in your data store, saying the most recent edit lock is for user A and expires at 12:42pm. User A can edit as much as he likes in that time. If he's done earlier, he can click a "finished" button that removes the lock entry. You might even give him a "more time" button that updates the lock-expiry timestamp to 60 minutes from now.

If user B comes along and tries to edit the file, your app checks the list and sees that this file is locked until 12:42pm today. If user A goes away and never finishes, or saves and forgets to unlock, or if the app crashes, you don't need to worry about unlocking or cleaning up. User B just has to wait around until past 12:42, and then your app will ignore the existing lock entry because it's expired.

A lot of wikis use a method similar to this. It may not be perfect, but it's easy for users to understand, and doesn't require any operator maintenance.

度的依靠╰つ 2024-08-21 04:55:10

您可以使用我的库从多个应用程序访问文件。

您可以从 nuget 安装它:Install-Package Xabe.FileLock

如果您想了解有关它的更多信息,请检查
https://github.com/tomaszzmuda/Xabe.FileLock

ILock fileLock = new FileLock(file);
if(fileLock.Acquire(TimeSpan.FromSeconds(15), true))
{
    using(fileLock)
    {
        // file operations here
    }
}

fileLock.Acquire 方法将返回 true仅当可以锁定该对象独占的文件时。
但上传文件的应用程序也必须在文件锁定下进行。
如果对象不可访问,则方法返回 false。

因此,如果您想使用它,您可以在第一个用户打开文件进行编辑时创建锁定,并在会话过期或用户更改页面后将其处置。

You can use my library for accessing files from multiple apps.

You can install it from nuget: Install-Package Xabe.FileLock

If you want more information about it check
https://github.com/tomaszzmuda/Xabe.FileLock

ILock fileLock = new FileLock(file);
if(fileLock.Acquire(TimeSpan.FromSeconds(15), true))
{
    using(fileLock)
    {
        // file operations here
    }
}

fileLock.Acquire method will return true only if can lock file exclusive for this object.
But app which uploading file must do it in file lock too.
If object is inaccessible metod returns false.

So if you want use it, you create lock when first user open file to edit and dispose it after session expired or user change page.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文