首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用互斥以确保异步应用程序的单个实例

使用互斥以确保异步应用程序的单个实例
EN

Stack Overflow用户
提问于 2020-12-17 14:46:22
回答 2查看 1.2K关注 0票数 1

我试图使用C#互斥锁来确保我的应用程序在单个实例中运行。因此,应用程序在开始时获取全局互斥,并在退出时释放它。如果互斥获取失败,则显示错误。应用程序是一个控制台应用程序,它主要是异步的(主要方法是异步)。基本上,互斥是在主方法开始时获得的,并在它的末尾释放。问题是主方法是异步的,它的结束可能在与开始不同的线程上执行。因此,当我试图释放互斥对象时,我得到了“对象同步方法是从不同步的代码块调用的”异常,因为互斥不能从另一个线程中释放。但是我不使用互斥来进行线程间同步,而是使用它来进行进程间同步。所以我并不关心哪个线程释放互斥,因为它保证获取和发布不会相互冲突。我知道有两种方法可以避免这个错误:

  • 对互斥对象使用单独的线程(此线程将获取互斥体,然后阻止并等待应用程序退出,然后释放互斥体)
  • 使用具有同步上下文的主线程,这将允许在同一线程上运行等待延续。

这两种方式似乎都太麻烦了。是否有更好的方法来确保异步应用程序的单个实例?

EN

回答 2

Stack Overflow用户

发布于 2020-12-17 15:59:04

虽然您可以使用您提到的任何一种方法,但使用命名信号量而不是命名互斥对象可能会更简单。

与互斥对象不同,信号量不关心哪个线程释放它们。

票数 2
EN

Stack Overflow用户

发布于 2020-12-17 18:51:11

您可以使用同步Main入口点。对于控制台应用程序来说,阻塞启动线程并不是什么大事。与GUI应用程序不同的是,在执行异步操作时,这个线程没有什么可做的。这就是当您使用async Task Main作为入口点时所发生的事情。

代码语言:javascript
复制
public static void Main(string[] args)
{
    var mutex = new Mutex(false, Assembly.GetEntryAssembly().GetName().Name);
    if (!mutex.WaitOne(0))
    {
        Console.WriteLine($"Already running. Press any key to continue . . .");
        Console.ReadKey();
        Environment.Exit(1);
    }
    try
    {
        MainAsync(args).GetAwaiter().GetResult();
    }
    finally
    {
        mutex.ReleaseMutex();
    }
}

public static async Task MainAsync(string[] args)
{
    // Main body here
}

顺便说一句,您应该查看关于可能的竞赛条件的问题,这可能会导致AbandonedMutexException。我想种族状况是微妙的,因为我无法复制它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65342900

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档