如何重新启动单个实例winforms应用程序

时间:2009-06-30 13:40:00

标签: c#

我有一个应用程序,我每天早上凌晨2点使用

重启

Application.Restart();

问题是几周后检查显示有大约6个实例正在运行。

我尝试使用

来限制实例数
 bool IsOwned;
 Mutex m = new Mutex(true, Name, out IsOwned);
 if (!IsOwned)
         Environment.Exit(0);

但由于某些原因,最近停止的实例仍然可见,但这至少不起作用......或者至少这是我的解释,因此应用程序没有重新开始。

我哪里出错了?

4 个答案:

答案 0 :(得分:3)

确保在应用程序退出事件上挂起释放互斥锁并关闭互斥锁的方法。

答案 1 :(得分:3)

任何机会,你使用多个线程吗?如果您不关闭后台线程,即使通过调用Application.Restart,它们也会使您的进程保持运行。

我已粘贴下面的一些代码来演示此行为。要查看它,请使用下面的代码编译测试项目并运行它。 (您需要在表单上放置1个按钮并分配我在下面的代码中定义的单击处理程序。)

启动任务管理器,转到“处理”选项卡,并确保将PID(进程ID)列添加到视图中。

每次单击该按钮时,应用程序都会重新启动,但您应该看到旧进程仍然挂在内存中(由于后台线程没有关闭)。


    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // start a background thread that will never be exited.
            System.Threading.Thread thread = new System.Threading.Thread(delegate() { while (true) System.Threading.Thread.Sleep(1000); });
            thread.Start();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Application.Restart();
        }
}

假设这是你的问题,纠正它的最好方法是在你的后台线程中加入某种检查(即使bool标志会这样做)。让他们定期检查退出,并在您的应用关闭时正常退出。

注意:您可以将线程的background属性设置为true,它将自动退出,但是如果您这样做,则无法控制线程退出时执行的指令,因此您不能执行任何类型的清理。最好编写自己的支票。

答案 2 :(得分:2)

我过去遇到过这个问题,而我认为问题是在第二个实例的互斥锁之前没有释放正在运行的实例关闭的互斥锁,启动时正在检查它。为了解决这个问题,我所做的是提供了一种方法来将控制传递回我的主表单,并指示重新启动;这样重启的Shutdown部分不必执行除退出之外的任何任务。

答案 3 :(得分:1)

首先......你为什么每天都需要重启一个应用程序?

我猜这是一个比每天凌晨2点重启的应用程序更好的解决方案。

例如,您可能有内存泄漏...如评论中所述。解决这个问题可能是一个更好的工作重点。大多数程序员都会考虑预先重新启动应用程序以避免内存泄漏,包括我自己,黑客。