确保只有一个应用程序实例 [英] Ensuring only one application instance
问题描述
可能的重复:
创建单实例的正确方法是什么申请?
我有一个 Winforms 应用程序,它通过以下代码启动启动画面:
I have a Winforms app, which launches a splash screen via the following code:
Hide();
bool done = false;
// Below is a closure which will work with outer variables.
ThreadPool.QueueUserWorkItem(x =>
{
using (var splashForm = new SplashScreen())
{
splashForm.Show();
while (!done)
Application.DoEvents();
splashForm.Close();
}
});
Thread.Sleep(3000);
done = true;
以上内容位于主窗体的代码隐藏中,并从加载事件处理程序中调用.
The above is in the main form's codebehind and called from the load event handler.
但是,我如何确保一次只加载一个应用程序实例?在主窗体的加载事件处理程序中,我可以检查进程列表是否在系统上(通过 GetProcessesByName(...)),但有没有更好的方法?
However, how can I ensure that only one instance of the application will load at a time? In the load event handler of the main form, I could check if the process list is on the system (via GetProcessesByName(...)), but is there a better method?
使用 .NET 3.5.
Using .NET 3.5.
推荐答案
GetProcessesByName 是检查另一个实例是否正在运行的缓慢方法.最快、最优雅的方法是使用互斥锁:
GetProcessesByName is slow way of checking if another instance is running. The fastest and elegant method is using mutex:
[STAThread]
static void Main()
{
bool result;
var mutex = new System.Threading.Mutex(true, "UniqueAppId", out result);
if (!result)
{
MessageBox.Show("Another instance is already running.");
return;
}
Application.Run(new Form1());
GC.KeepAlive(mutex); // mutex shouldn't be released - important line
}
另请记住,您提供的代码不是最佳方法.正如在循环中调用 DoEvents() 的评论之一所建议的那样,这不是最好的主意.
Please also bear in mind that the code you presented is not the best approach. As it was advised in one of comments calling DoEvents() in a loop is not the best idea.
这篇关于确保只有一个应用程序实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!