我开发了一个Windows服务,可以监视新文件的文件夹。我的问题是,当发生异常时,服务停止工作。该服务的主要目的是: 1.观察文件夹以进行文件创建 2.读取文件 3.在数据库中插入文件的数据 我真正想做的是不要丢失任何文件插入!必须读取每个新文件并将其数据插入数据库中。 但是,如果发生异常,例如“进程无法访问文件'c:\ newfile.txt',因为它正被另一个进程使用。”,该进程将停止。我的服务代码是:
public partial class weatherService : ServiceBase
{
private FileSystemWatcher FSW;
private FswHandler Handler;
public weatherService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
FSW = new FileSystemWatcher("c:\\cvvv", "*.txt");
Handler = new FswHandler();
FSW.Created += Handler.OnEvent;
FSW.EnableRaisingEvents = true;
}
protected override void OnStop()
{
FSW.EnableRaisingEvents = false;
FSW.Dispose();
}
protected override void OnPause()
{
FSW.EnableRaisingEvents = false;
}
protected override void OnContinue()
{
FSW.EnableRaisingEvents = true;
}
}
处理程序代码是:
public class FswHandler
{
private string[] data;
private StreamReader reader;
private StreamWriter sw;
public void OnEvent(Object source, FileSystemEventArgs Args)
{
LogEvent(" [reading file] ");
readFile(Args.FullPath, Args.Name);
}
public void LogEvent(string msg) {
sw = new StreamWriter("C:\\Users\\Olga\\Desktop\\weatherlog.txt", true);
sw.WriteLine("Action : "+ msg +" occured in " + DateTime.Now.ToString());
sw.Close();
}
public void readFile(string path, string filename)
{
LogEvent(" [got in readFile] to read file " + filename);
try
{
reader = new StreamReader(path);
}
catch (Exception ex)
{
LogEvent(ex.Message);
}
try
{
reader = File.OpenText(path);
}
catch (Exception ex)
{
LogEvent(ex.Message);
}
string titlesLine;
string valuesLine;
LogEvent(" [getting 1st line] ");
titlesLine = reader.ReadLine();
LogEvent(" [getting 2nd line] ");
valuesLine = reader.ReadLine();
LogEvent(" [splitting 2nd line] ");
data = valuesLine.Split(new Char[] { ' ', '\t' });
LogEvent(" [starting inserting] ");
insData(filename);
reader.Close();
}
public void insData(string filename) {
string connString = "server=83.212.92.197;port=3306;database=mydata;uid=distusr;pwd=usdist1";
MySqlConnection conn = new MySqlConnection(connString);
MySqlCommand command = conn.CreateCommand();
DateTime cdt = System.DateTime.Now;
String.Format("{0:MM/dd/yyyy HH:mm:ss}", cdt);
string dt = cdt.ToString();
int space_pos = dt.IndexOf(" ");
string date = dt.Substring(0, space_pos);
string time = dt.Substring(space_pos+1, dt.Length-space_pos+1);
command.CommandText = "INSERT INTO datainput(filename, measDate, measTime, out2, out3, out4, out5, out6, out7, out8, out9, out10," +
"out11, out12, out13, out14, out15, out16, out17, out18, out19, out20," +
"out21, out22, out23, out24, out25, out26, out27, out28, out29, out30," +
"out31, out32, out33, out34, out35, out36, out37, out38, out39, out40," +
"out41, out42, out43) VALUES ('" + filename + "','" + date + "','" + time +
"','" + data[14] + "','" + data[15] + "','" + data[16] + "','" + data[17] + "'," +
"'" + data[18] + "','" + data[19] + "','" + data[20] + "','" + data[21] + "','" + data[22] +
"','" + data[23] + "'," + "'" + data[24] + "','" + data[25] + "','" + data[26] +
"','" + data[27] + "','" + data[28] + "'," +"'" + data[29] + "','" + data[30] +
"','" + data[31] + "','" + data[32] + "','" + data[33] + "'," + "'" + data[34] +
"','" + data[35] + "','" + data[36] + "','" + data[37] + "','" + data[38] + "'," +
"'" + data[39] + "','" + data[40] + "','" + data[41] + "','" + data[42] + "','" + data[43] +
"'," + "'" + data[44] + "','" + data[45] + "','" + data[46] + "','" + data[47] +
"','" + data[48] + "'," + "'" + data[49] + "','" + data[50] + "','" + data[51] +
"','" + data[52] + "','" + data[53] + "','" + data[54] + "','" + data[55] + "')";
LogEvent(" [opening database] ");
try{
conn.Open();
}
catch (Exception ex){
LogEvent(ex.Message);
}
LogEvent(" [executing query] ");
try
{
command.ExecuteNonQuery();
}
catch (Exception ex){
LogEvent(ex.Message);
}
LogEvent(" [data have been inserted] ");
conn.Close();
}
}
我可以做些什么来避免丢失文件?我也试过
protected void DelayExecution(int nSeconds)
{
DateTime end = DateTime.UtcNow.AddSeconds (nSeconds);
while (DateTime.UtcNow < end){}
}
try
{
reader = File.OpenText(path);
}
catch (Exception ex)
{
LogEvent(ex.Message);
DelayExecution(2);
readFile(path, filename);
}
但问题仍然存在。在这种情况下,它从函数开始并在进程在db中插入数据之后再进入[获取第1行]。我使用LogEvent,所以我可以调试我的服务,这就是我有很多LogEvents执行的原因。
任何帮助都会很棒......
答案 0 :(得分:0)
您可以尝试在具有Thread.Sleep的循环中使用此扩展方法:
/// <summary>
/// Extension methods for FileInfo
/// </summary>
public static class ExtensionMethods_FileInfo
{
/// <summary>
/// Verifies if the file is in use
/// </summary>
/// <param name="fi">Original FileInfo object</param>
/// <returns>Returns a boolean value with the state of the file</returns>
public static Boolean IsInUse(this FileInfo fi)
{
try
{
if (File.Exists(fi.FullName))
File.Move(fi.FullName, fi.FullName);
return false;
}
catch (IOException)
{
return true;
}
}
}
我建议您不要在“catch”部分编写代码(除了日志记录),因为它可能会导致更多错误。
while (new FileInfo(path).IsInUse())
System.Threading.Thread.Sleep(1000);
// Then do your job...