首页 > 解决方案 > C# FileSystemWatcher - 多个事件

问题描述

我创建了此 Windows 服务,当文件 .txt/.csv 出现在特定文件夹中时,获取此文件并将第一行放入数据库中一次。问题是,一旦服务启动,事件处理程序“处理”仅 1 次添加文件,事实上,当我删除文件并尝试放置另一个文件时,服务不会在数据库中添加数据,我必须手动重新启动它。我需要的解决方案是,该服务一旦启动,就会保持活动状态,并创建一个文件系统观察器(/eventhandler),它像服务一样运行,每次添加新文件时,它都会将第一行插入数据库

namespace myServiceDB_D1
{
public partial class ServiceD1 : ServiceBase
{
    public ServiceD1()
    {
        InitializeComponent();
    }

    Timer mainTimer = new Timer(); // name space(using System.Timers;)  

    public static FileSystemWatcher watcher;

    protected override void OnStart(string[] args)
    {
        WriteToFile("Service is started at " + DateTime.Now);
        mainTimer.Elapsed += new ElapsedEventHandler(main);
        mainTimer.Interval = 2 * 1000; //Interval of 2sec
        mainTimer.AutoReset = false;
        //mainTimer.Enabled = true;
        mainTimer.Start();
    }

    private void main(object sender, EventArgs args)
    {
        mainTimer.Stop();
        mainTimer.Dispose();

        watcher = new FileSystemWatcher
        {
            Path = @"C:\Users\user\Desktop\newData",
            NotifyFilter = NotifyFilters.LastWrite,
        };
        watcher.Created += FileSystemWatcher_Changed;
        watcher.Renamed += FileSystemWatcher_Renamed;
        watcher.Changed += FileSystemWatcher_Changed;
        watcher.EnableRaisingEvents = true;
    }

    

    public static void FileSystemWatcher_Changed(object source, FileSystemEventArgs e)
    {
        string path = e.FullPath;
        DataTable imported_data = GetDataFromFile(path);
        if (imported_data == null) return;
        SaveImportDataToDatabase(imported_data);

    }

    private static DataTable GetDataFromFile(string path)
    {
        DataTable importedData = new DataTable();
        try
        {
            using (StreamReader sr = new StreamReader(path))
            {

                string[] headerColumns = header.Split(';');
                foreach (string headerColumn in headerColumns){
                    importedData.Columns.Add(headerColumn);
                }
               
                 string[] headerColumns = {"misura_durezza"};
                foreach (string headerColumn in headerColumns){
                    importedData.Columns.Add(headerColumn);
                }
                 
                while (!sr.EndOfStream)
                {
                    string line = sr.ReadLine();
                    if (string.IsNullOrEmpty(line))
                    {
                        MessageBox.Show("no file data");
                        return null;
                    }
                    
                    DataRow importedRow = importedData.NewRow();
                    importedRow[0] = line.ToString();
                    importedData.Rows.Add(importedRow);
                }
            }


        }
        catch (Exception e)
        {
            Console.WriteLine("the file could not be read:");
            Console.WriteLine(e.Message);
        }

        return importedData;
    }

    private static void SaveImportDataToDatabase(DataTable imported_data)
    {

        using (MySqlConnection conn = new MySqlConnection("Server=localhost;Database=controlmachine;Uid=root;Pwd=")) 
        {
            try
            {
                WriteToFile($"Connection to database");
                conn.Open();
                WriteToFile($"Connected to database");
                foreach (DataRow importRow in imported_data.Rows)
                {
                    
                    MySqlCommand cmd = conn.CreateCommand();
                    cmd.CommandText = "INSERT INTO temp_d1 (misura_durezza) VALUES (@misura_durezza)";


                    WriteToFile($"Creating query");
                    cmd.Parameters.AddWithValue("@misura_durezza", importRow["misura_durezza"]);

                    WriteToFile($"Executing query");
                   
                    cmd.ExecuteNonQuery();
                }
            }
            catch
            {
                WriteToFile($"Failed to insert into the database");
            }
        }
    }

    public static void FileSystemWatcher_Renamed(object source, RenamedEventArgs e)
    {
        WriteToFile($"File Renamed: {e.OldFullPath} renamed to {e.FullPath}");
    }
    private void OnElapsedTime(object source, ElapsedEventArgs e)
    {
        WriteToFile("Service is recalled at " + DateTime.Now);
    }
    protected override void OnStop()
    {

        WriteToFile("Service is stopped at " + DateTime.Now);
    }

    public static void WriteToFile(string Message)
    {
        string path = "C:\\Users\\user\\Desktop\\serviceLog";
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
       
        string filepath = "C:\\Users\\user\\Desktop\\serviceLog\\serviceLog_D1_" + DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
        if (!File.Exists(filepath))
        {
            // Create a file to write to.   
            using (StreamWriter sw = File.CreateText(filepath))
            {
                sw.WriteLine(Message);
            }
        }
        else
        {
            using (StreamWriter sw = File.AppendText(filepath))
            {
                sw.WriteLine(Message);
            }
        }
    }
}

}

标签: c#windowsvisual-studiowindows-services

解决方案


你有一个错误,你订阅了同一个事件两次。

 watcher.Created += FileSystemWatcher_Changed;

推荐阅读