I have an application that I restart at 2 am every morning using
我有一个应用程序,我每天早上2点重新启动使用
Application.Restart();
the problem is that a inspection a couple of weeks later shows that there are 6 or so instances running.
问题是几周后检查显示有大约6个实例正在运行。
I tried to limit the number of instances by using
我试图通过使用限制实例数
bool IsOwned;
Mutex m = new Mutex(true, Name, out IsOwned);
if (!IsOwned)
Environment.Exit(0);
But this didn't work as for some reason the recently stopped instance was still visible...or at least that's my interpretation and as a result the application didn't reatart.
但是由于某些原因,最近停止的实例仍然可见,这不起作用......或者至少这是我的解释,因此应用程序没有重新启动。
Where have I gone wrong?
我哪里出错了?
4 个解决方案
#1
Make sure that you hook on application exit event a method that releases the mutex and closes it.
确保在应用程序退出事件上挂起释放互斥锁并关闭互斥锁的方法。
#2
By any chance, are you using multiple threads? If you don't shut down your background threads, they will keep your process running, even through a call to Application.Restart.
不管怎样,你使用多线程吗?如果不关闭后台线程,即使通过调用Application.Restart,它们也会使进程保持运行。
I have pasted in some code below that demonstrates this behavior. To see it, compile a test project with the code below and run it. (you will need to put 1 button on the form and assign the click handler that I have defined in the code below).
我已经粘贴了下面的一些代码来演示这种行为。要查看它,请使用下面的代码编译测试项目并运行它。 (您需要在表单上放置1个按钮并分配我在下面的代码中定义的单击处理程序)。
Start Task Manager, go to the Process tab, and make sure to add the PID (process id) column to the view.
启动任务管理器,转到“进程”选项卡,并确保将PID(进程ID)列添加到视图中。
Each time you click the button, the app will restart, but you should see the old process still hung in memory (due to a background thread that was not closed down).
每次单击该按钮时,应用程序都将重新启动,但您应该看到旧进程仍然挂在内存中(由于后台线程未关闭)。
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();
}
}
Assuming that this is your problem, the best way to correct it is to put some kind of a check into your background threads (even a bool flag will do). Have them check for exited periodically and and exit gracefully when your app shuts down.
假设这是你的问题,纠正它的最好方法是在你的后台线程中加入某种检查(即使是bool标志也可以)。让他们定期检查退出,并在您的应用关闭时正常退出。
Note: you could set the thread's background property to true, and it will be exited automatically, but if you do that, you don't have control over which instruction the thread is executing when it exits, so you can't perform any type of cleanup. It's best to code your own check.
注意:您可以将线程的background属性设置为true,并且它将自动退出,但如果您这样做,则无法控制线程退出时执行的指令,因此您无法执行任何类型清理。最好编写自己的支票代码。
#3
I have run into this problem in the past, and what I believe the issue was is that the mutex of the running instance getting shutdown was not being released before the mutex of the second instance, starting up was checking for it. To solve this, what I did was provided a means to pass back control to my main form with an indication to restart; so that the Shutdown part of the Restart didn't have to perform any tasks except for exiting.
我在过去遇到过这个问题,而我认为问题是在第二个实例的互斥锁之前没有释放正在运行的实例关闭的互斥锁,启动时正在检查它。为了解决这个问题,我所做的是提供了一种方法来将控制传递回我的主表单,并指示重新启动;这样重启的Shutdown部分除了退出之外不必执行任何任务。
#4
First off... why do you need to restart an app every day?
首先......你为什么每天都要重启一个应用程序?
I'm guessing theres a better solution than an app that restarts itself at 2 AM every day.
我猜这是一个比每天凌晨2点重启的应用程序更好的解决方案。
For example, you may have a memory leak... as described in your comment. Addressing that might be a better place to focus your efforts. Restarting an app preiodically to avoid a memory leak would be considered by most programmers, including myself, a hack.
例如,您可能有内存泄漏...如评论中所述。解决这个问题可能是一个更好的工作重点。大多数程序员(包括我自己,黑客)会考虑预先重新启动应用程序以避免内存泄漏。
#1
Make sure that you hook on application exit event a method that releases the mutex and closes it.
确保在应用程序退出事件上挂起释放互斥锁并关闭互斥锁的方法。
#2
By any chance, are you using multiple threads? If you don't shut down your background threads, they will keep your process running, even through a call to Application.Restart.
不管怎样,你使用多线程吗?如果不关闭后台线程,即使通过调用Application.Restart,它们也会使进程保持运行。
I have pasted in some code below that demonstrates this behavior. To see it, compile a test project with the code below and run it. (you will need to put 1 button on the form and assign the click handler that I have defined in the code below).
我已经粘贴了下面的一些代码来演示这种行为。要查看它,请使用下面的代码编译测试项目并运行它。 (您需要在表单上放置1个按钮并分配我在下面的代码中定义的单击处理程序)。
Start Task Manager, go to the Process tab, and make sure to add the PID (process id) column to the view.
启动任务管理器,转到“进程”选项卡,并确保将PID(进程ID)列添加到视图中。
Each time you click the button, the app will restart, but you should see the old process still hung in memory (due to a background thread that was not closed down).
每次单击该按钮时,应用程序都将重新启动,但您应该看到旧进程仍然挂在内存中(由于后台线程未关闭)。
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();
}
}
Assuming that this is your problem, the best way to correct it is to put some kind of a check into your background threads (even a bool flag will do). Have them check for exited periodically and and exit gracefully when your app shuts down.
假设这是你的问题,纠正它的最好方法是在你的后台线程中加入某种检查(即使是bool标志也可以)。让他们定期检查退出,并在您的应用关闭时正常退出。
Note: you could set the thread's background property to true, and it will be exited automatically, but if you do that, you don't have control over which instruction the thread is executing when it exits, so you can't perform any type of cleanup. It's best to code your own check.
注意:您可以将线程的background属性设置为true,并且它将自动退出,但如果您这样做,则无法控制线程退出时执行的指令,因此您无法执行任何类型清理。最好编写自己的支票代码。
#3
I have run into this problem in the past, and what I believe the issue was is that the mutex of the running instance getting shutdown was not being released before the mutex of the second instance, starting up was checking for it. To solve this, what I did was provided a means to pass back control to my main form with an indication to restart; so that the Shutdown part of the Restart didn't have to perform any tasks except for exiting.
我在过去遇到过这个问题,而我认为问题是在第二个实例的互斥锁之前没有释放正在运行的实例关闭的互斥锁,启动时正在检查它。为了解决这个问题,我所做的是提供了一种方法来将控制传递回我的主表单,并指示重新启动;这样重启的Shutdown部分除了退出之外不必执行任何任务。
#4
First off... why do you need to restart an app every day?
首先......你为什么每天都要重启一个应用程序?
I'm guessing theres a better solution than an app that restarts itself at 2 AM every day.
我猜这是一个比每天凌晨2点重启的应用程序更好的解决方案。
For example, you may have a memory leak... as described in your comment. Addressing that might be a better place to focus your efforts. Restarting an app preiodically to avoid a memory leak would be considered by most programmers, including myself, a hack.
例如,您可能有内存泄漏...如评论中所述。解决这个问题可能是一个更好的工作重点。大多数程序员(包括我自己,黑客)会考虑预先重新启动应用程序以避免内存泄漏。