我试图使用C#互斥锁来确保我的应用程序在单个实例中运行。因此,应用程序在开始时获取全局互斥,并在退出时释放它。如果互斥获取失败,则显示错误。应用程序是一个控制台应用程序,它主要是异步的(主要方法是异步)。基本上,互斥是在主方法开始时获得的,并在它的末尾释放。问题是主方法是异步的,它的结束可能在与开始不同的线程上执行。因此,当我试图释放互斥对象时,我得到了“对象同步方法是从不同步的代码块调用的”异常,因为互斥不能从另一个线程中释放。但是我不使用互斥来进行线程间同步,而是使用它来进行进程间同步。所以我并不关心哪个线程释放互斥,因为它保证获取和发布不会相互冲突。我知道有两种方法可以避免这个错误:
这两种方式似乎都太麻烦了。是否有更好的方法来确保异步应用程序的单个实例?
发布于 2020-12-17 15:59:04
虽然您可以使用您提到的任何一种方法,但使用命名信号量而不是命名互斥对象可能会更简单。
与互斥对象不同,信号量不关心哪个线程释放它们。
发布于 2020-12-17 18:51:11
您可以使用同步Main入口点。对于控制台应用程序来说,阻塞启动线程并不是什么大事。与GUI应用程序不同的是,在执行异步操作时,这个线程没有什么可做的。这就是当您使用async Task Main作为入口点时所发生的事情。
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。我想种族状况是微妙的,因为我无法复制它。
https://stackoverflow.com/questions/65342900
复制相似问题