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

C# 如何重新启动单实例winforms应用程序,c#,C#,我有一个应用程序,我每天早上2点用 Application.Restart() 问题是,几周后的一次检查显示,大约有6个实例正在运行 我试图通过使用 bool IsOwned; Mutex m = new Mutex(true, Name, out IsOwned); if (!IsOwned) Environment.Exit(0); 但由于某些原因,最近停止的实例仍然可见,这不起作用……或者至少这是我的解释,因此应用程序没有重新启动 我哪里出错了 确保在应用程序退出

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

Application.Restart()

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

我试图通过使用

 bool IsOwned;
 Mutex m = new Mutex(true, Name, out IsOwned);
 if (!IsOwned)
         Environment.Exit(0);
但由于某些原因,最近停止的实例仍然可见,这不起作用……或者至少这是我的解释,因此应用程序没有重新启动


我哪里出错了

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

首先。。。为什么你每天都需要重新启动应用程序

我猜有比每天凌晨2点重启的应用更好的解决方案


例如,您可能有内存泄漏。。。如你评论中所述。解决这个问题可能是一个更好的集中精力的地方。大多数程序员(包括我自己)都会认为,为了避免内存泄漏而预先重启应用程序是一种黑客行为。

我过去遇到过这个问题,我认为问题在于,正在运行的实例关闭时的互斥体在第二个实例的互斥体之前没有被释放,启动时正在检查它。为了解决这个问题,我所做的是提供一种方法,将控件传递回主窗体,并指示重新启动;这样重新启动的关机部分就不必执行任何任务,只需退出即可。

您是否正在使用多个线程?如果您不关闭后台线程,即使通过调用Application.Restart,它们也会使您的进程保持运行

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

启动任务管理器,转到流程选项卡,并确保将PID(流程id)列添加到视图中

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

假设这是您的问题,最好的纠正方法是在后台线程中进行某种检查(即使是bool标志也可以)。让他们定期检查是否退出,并在应用程序关闭时优雅地退出


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

这与问题有什么关系?事实上,我想每天凌晨2点重新开始。为什么很重要。。。我有一种感觉,这是大多数人会想知道的第一件事。@Brad-为什么很重要,因为(就像这里的其他问题一样)有时候根本问题可以解决,让你的表面问题变得毫无意义。这个问题是完全合法的,尽管我可能会把它发布在评论中,而不是作为一个实际的答案。它是一个独立的应用程序,在动态创建的图形对象中显示来自工业工厂的实时数据,这些图形对象连接到各种SQL Server。它全天候连续运行。大约3周后,分配的内存似乎太多了。我已经检查了绘制例程,看看是否有资源没有被正确处理,但没有找到任何东西。在此期间,在我发现真正的问题之前,这是绕过潜在内存不足异常的最简单方法。是的,我也认为这是一种黑客行为。我宁愿不必重新启动应用程序。但现实是,它是一个一次性应用程序,安装在工厂地板上的一个大LCD屏幕上,我希望它现在就运行,而不是等到我有时间调查和解决根本问题时。然而,我正在努力找到问题所在。

    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();
        }
}