在我的程序中,我在每次循环迭代中接近文本文件,以免丢失任何运行数据。这是残酷的无效,我昨天仍然丢失了这些数据。
我有2个队列 - "我做了什么"和"做什么"。一段时间后,我需要结束此应用程序并记住下一个应用程序运行的这些队列。我通常用Ctrl + C来杀死应用程序。
在app kill之后有没有办法将这些队列保存到文件中?或者如何正确地将控制台应用程序作为用户结束。
是否可以原子地运行一段代码? 我的意思是当我更新一些"队列文件"通过删除它的第一行我需要将整个文件复制到tmp而不是删除原始文件,而不是将tmp文件复制到原始文件。但有时我会在orig之后立即按Ctrl + C.文件删除,我丢失了一个队列。
答案 0 :(得分:2)
Ctrl + C不必杀死应用程序 - 您可以使用Console.CancelKeyPress
事件正确处理关闭。至于当用户点击关闭按钮时,你运气不好 - 这实际上是残忍地杀死了这个过程。
您的应用程序应该支持正常关闭。例如,您可以在Console.CancelKeyPress
中显示已取消的取消令牌,并且您的代码应该偶尔检查令牌(当您在一个安全的地方时终止)以查看是否请求关闭。
作为额外措施,您可以尝试使用一些更安全的操作措施。例如,您可以重命名它,而不是删除原始文件。如果您的处理在中间失败,文件仍然存在,您可以在重新启动应用程序时恢复它。只有在完全处理和复制新文件时才会删除原始文件。
答案 1 :(得分:1)
答案 2 :(得分:0)
看起来你可以挂钩到CTRL-C或CTRL-BREAK信号,以便优雅地退出你的应用程序。
class Program
{
//https://msdn.microsoft.com/en-us/library/windows/desktop/ms683231(v=vs.85).aspx
private const int STD_INPUT_HANDLE = -10;
private const uint ENABLE_PROCESSED_INPUT = 0x0001;
[DllImport("Kernel32.dll")]
private static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("Kernel32.dll")]
private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
[DllImport("Kernel32.dll")]
private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint dwMode);
static void Main(string[] args)
{
IntPtr handle = GetStdHandle(STD_INPUT_HANDLE);
uint mode;
GetConsoleMode(handle, out mode);
mode &= ~ENABLE_PROCESSED_INPUT;
SetConsoleMode(handle, mode);
new Thread(() =>
{
while (true)
{
var chara = Console.ReadKey();
if (chara.KeyChar == 3)
{
Console.WriteLine("ctrl-c");
//signal to gracefully exit
}
Console.WriteLine("c:{0}", chara);
}
}).Start();
}
}