【问题标题】:C# How to safely end a thread that saves to fileC#如何安全地结束保存到文件的线程
【发布时间】:2016-09-23 16:11:26
【问题描述】:
我正在编写一个脚本,该脚本会在应保存的更改后 3 秒自动保存,并希望在发生其他更改时重置 3 秒计时器。我也在使用线程,因为我不希望程序在磁盘繁忙等情况下卡顿。
void SaveTimer()
{
Thread.Sleep(3000); //wait 3 seconds
Save(); //writes binary file to disk
}
在上面的代码中,一个线程以“StartTimer”开始。每次发生更改时,我都可以终止线程并重新启动它,但是如果线程正在保存到磁盘中,这可能会导致问题。我不确定如何安全地重置等待时间。任何想法将不胜感激,谢谢。
【问题讨论】:
标签:
c#
multithreading
file
io
persistence
【解决方案1】:
根据您的问题和后续的 cmets,我可以建议您两个选项,以及一些额外的“警告”:
- 如果您的线程在每次迭代时循环执行某些内容,您可以设置一个 volatile 布尔标志,使其在完成当前迭代后退出。
然后,当您希望线程停止时,只需将标志设置为 true,它将在下次检查条件时停止。
- 如果您不能等待迭代完成并且需要立即停止它,您可以选择 Thread.Abort,但请绝对确保您无法保留打开的文件句柄、套接字、锁或其他类似的东西这处于不一致的状态。
【解决方案2】:
1) 我建议您在尝试写入之前检查该文件是否已被写入。
void SaveTimer()
{
try
{
using (Stream stream = new FileStream(filename, FileMode.Open))
{
yourTimer.Stop();
Save();
yourTimer.Start();
}
}
catch { Thread.Sleep(3000); }
}
}
- 如果可能,最好重构代码以避免使线程进入休眠状态。
【解决方案3】:
根据数据的性质,您可能希望写入一个大的空文件,然后将其保持打开状态,以便在专用进程上进行读写。
无需重写文件,只需将需要更改的行传送到读/写线程即可。
为简单起见,文件应该足够大以至于不需要增长。这样你就创建了一个基本的数据库。