并发和多用户访问

时间:2015-11-20 06:49:09

标签: c# winforms concurrency

首先,我会解释一下情况。 我有一个存储在服务器上的GUI,应该获得多个用户访问权限。用户正在处理不同的选项卡(一种独立的工作区)。 现在,当用户输入选项卡时,应该为其他用户锁定(禁用)。其他用户应查看当前是否锁定了选项卡。 所以我的想法是:

  1. 创建一个文本文件,列出选项卡及其当前状态(已锁定 - 已解锁)。
  2. 如果该文件被修改,则线程每隔几秒检查一次。如果是,则读取它并禁用或启用GUI中的相应选项卡。 3.当用户想要输入选项卡时,如果选项卡已解锁(可能是用户比线程更快),请检查文件并将其设置为锁定。
  3. 当用户离开标签然后将其设置为未锁定时。

    现在我的问题是:

    有没有更好或更有效的方法来处理这种情况?

    如何避免两个用户想要同时切换到同一个标签的情况,读取标签是否已解锁并同时写入文件?

    是否还有更多错误案例?

3 个答案:

答案 0 :(得分:4)

您可以使用正确的SQL DBMS和事务来保持检查和更新原子,而不是文本文件。如果您正确地编写查询,它将涵盖所有边缘情况。

类似的东西:

begin tran
if not exists(select top 1 1 from tabs where id=@id and active=1)
begin
    update tabs set active=1 where id=@id
    select 1 --result
end
else
begin
    select 0 --result
end
commit tran

甚至更好,而不是仅仅存储true / false表示选项卡正在使用中,存储用户标识符以了解谁在使用它。这样,如果您的应用程序在发布之前崩溃/结束,您可以在下次同一用户登录时手动释放它。您也可以为同一目的投入截止日期,并在应用程序联机时继续推送它。 / p>

答案 1 :(得分:0)

我从您的问题中了解到,您需要同步在不同计算机上运行的应用程序。您希望通过位于网络驱动器上的文件来执行此操作,该文件可从所有这些计算机访问,对吗?

除共享文件外,您可以使用IP /以太网广播或简单的同步服务器。

在所有这些解决方案中,共享文件最简单,但没有那么有效。

您可以使用与System.IO.FileSystemWatcher类似的技术代替它。如果是文件监视器,您将在锁定时为每个选项卡创建单个文件;并在标签发布时将其删除。

文件监视器使您不必重新读取文件的内容,而是在文件更改时引发事件。

这种方法可以在没有这么高负载的情况下工作。如果您计划> 50位用户,我认为开发特殊服务器以同步用户会更好。

简短说明:

  1. FileSystemWatcher控件放在表单上。
  2. 将属性Path设置为所需的网络路径(最好使用新的空目录)。
  3. 为事件CreateDelete创建处理程序:

    void fileSystemWatcher1_Created(object sender, FileSystemEventArgs e)
    {
        var tabName = Path.GetFileName(e.FullPath);
        var tab = tabControl1.TabPages[tabName];
    
        // Do not disable selected tab cause you're working with the tab
        // and you're locking it
        if (tab != tabControl1.SelectedTab)
            tab.Enabled = false;
    }
    
    void fileSystemWatcher1_Deleted(object sender, FileSystemEventArgs e)
    {
        var tabName = Path.GetFileName(e.FullPath);
        var tab = tabControl1.TabPages[tabName];
        tab.Enabled = true;
    }
    
  4. 当标签获得焦点时,您应该使用网络目录中的标签名称创建空文件:

    . . .
    var path = fileSystemWatcher1.Path;
    var filename = Path.Combine(path, tabControl1.SelectedTag.Name);
    using (File.Create(filename));
    

    当标签失去焦点时:您应该删除文件:

    var path = fileSystemWatcher1.Path;
    var filename = Path.Combine(path, tabControl1.SelectedTag.Name);
    File.Delete(filename);
    

答案 2 :(得分:-1)

我觉得xml文件比文本文件好。如问题中所指定,您需要维护xml文件中每个选项卡的状态,以指示它是否已锁定。您可以处理类型参数selectinge的标签控件的TabControlCancelEventArgs事件,并通过设置为true将取消选择该标签,使其具有属性Cancel。在此事件中,您可以检查xml文件以验证选项卡是否已锁定或解锁,如果已锁定,您可以设置e.Cancel=true并向用户发出此选项卡已锁定的消息。

您可以使用标签控件的deselecting事件来了解用户何时离开该标签,并将xml文件中该标签的状态更新为已解锁。