如何将 Citrix 中的 C# 程序实例限制为每用户 1 个

Spa*_*ter 2 c# mutex citrix multiple-instances

我有一个带有 C# 代码的 Windows 窗体应用程序,如下所示(针对 .NET Framework 4)。

在我的开发人员工作站上,此代码可以阻止我启动该程序的多个实例。但是,QA 有一个 Citrix 测试环境,每个用户仍然能够启动多个实例。

如何防止给定用户在 Citrix 中运行多个实例?

[STAThread]
static void Main(string[] args)
{
    bool isFirstInstance;
    Mutex m = new Mutex(true, "[App name goes here] mutex", out isFirstInstance);

    if (isFirstInstance)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run();

        // Prevent the just-in-time (JIT) compiler from optimizing away our Mutex.
        // See: http://www.ai.uga.edu/mc/SingleInstance.html
        GC.KeepAlive(m);
    }
}
Run Code Online (Sandbox Code Playgroud)

出于技术原因,我们希望限制实例数量。该程序使用自承载 WCF 与同一用户运行的另一个进程进行通信。我们只希望每个用户有一个该程序的实例。

我不知道有关 Citrix 环境的任何详细信息,但可以询问。

谢谢。

don*_*van 5

根据您想要的行为,使用本地或全局范围的互斥体可能是合适的。

将互斥锁与“Local\”一起使用将确保每个会话仅运行一个实例。但是,您的用户仍然可以在同一服务器上启动多个会话(取决于您的 Citrix 环境的配置方式),因此您的应用程序的多个实例在不同的会话中运行。

如果您希望 100% 每个用户在每个服务器上只有一个实例,那么您需要使用全局互斥锁。但是,您需要确保使用特定于用户的状态来命名互斥锁,例如

string globalMutexName = string.Format(
    CultureInfo.InvariantCulture,
    "Global\\AppName~{0}~{1}~some-unique-guid",
    Environment.UserDomainName,
    Environment.UserName);

_machineLocalAppInstanceMutex = new System.Threading.Mutex(true, globalMutexName, out mutexIsNew);

if (!mutexIsNew)
{
    Shutdown();
}
Run Code Online (Sandbox Code Playgroud)

另外,我会让互斥体成为一个类的成员,通常是您的主 App/Form 类,而不是使用 GC.KeepAlive