私も同様の問題を抱えていましたが、24時間年中無休で実行する必要のあるアプリでは見つけることができなかった管理不能なメモリリークに関連していました。お客様と一緒に、メモリ消費量が定義された値を超えた場合、アプリを再起動する安全な時間は午前3時であることに同意しました。
試してみApplication.Restart
ましたが、すでに実行中に新しいインスタンスを起動するメカニズムを使用しているようですので、別のスキームを選びました。私は、ファイルシステムが処理するトリックを使用して、ファイルシステムを作成したプロセスが停止するまで保持します。そのため、アプリケーションから、ファイルをディスクにドロップしましたがDispose()
、ハンドルはありませんでした。このファイルを使用して、「myself」実行可能ファイルと開始ディレクトリも送信しました(柔軟性を高めるため)。
コード:
_restartInProgress = true;
string dropFilename = Path.Combine(Application.StartupPath, "restart.dat");
StreamWriter sw = new StreamWriter(new FileStream(dropFilename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite));
sw.WriteLine(Application.ExecutablePath);
sw.WriteLine(Application.StartupPath);
sw.Flush();
Process.Start(new ProcessStartInfo
{
FileName = Path.Combine(Application.StartupPath, "VideoPhill.Restarter.exe"),
WorkingDirectory = Application.StartupPath,
Arguments = string.Format("\"{0}\"", dropFilename)
});
Close();
Close()
最後にアプリのシャットダウンが開始され、ここで使用したファイルハンドルは、StreamWriter
プロセスが実際に停止するまで開いたままになります。それで...
Reseter.exeが動作します。排他モードでファイルを読み取ろうとし、メインアプリが停止しなくなるまでファイルにアクセスできないようにしてから、メインアプリを起動し、ファイルを削除して存在します。私はそれがもっと簡単になることはできないと思います:
static void Main(string[] args)
{
string filename = args[0];
DateTime start = DateTime.Now;
bool done = false;
while ((DateTime.Now - start).TotalSeconds < 30 && !done)
{
try
{
StreamReader sr = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
string[] runData = new string[2];
runData[0] = sr.ReadLine();
runData[1] = sr.ReadLine();
Thread.Sleep(1000);
Process.Start(new ProcessStartInfo { FileName = runData[0], WorkingDirectory = runData[1] });
sr.Dispose();
File.Delete(filename);
done = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Thread.Sleep(1000);
}
}