.NET FileSystemWatcher不异步触发Created和ConnectionStateChanged事件

时间:2019-01-11 14:32:49

标签: .net asynchronous events connection filesystemwatcher

我有一个fileSystemWatcher.Created事件,该事件必须独立触发我的fileSystemWatcher.ConnectionStateChanged事件。我认为这可能是线程问题,但我尝试了所有我可能想到的不同异步更改……无济于事。有人可以帮忙吗?

问题: 如果我将许多文件(100个文件)转储到文件系统监视程序配置为监视的目录中,则可以看到我的HandleFileEvent方法正在触发。在触发HandleFileEvent方法时,将不会触发HandleConnectStateChanged方法。

设置: HandleFileEvent调用一个方法,该方法依次使用ADO.NET执行存储过程并将数据文件fileName插入数据库。 同样,HandleConnectStateChanged方法调用一种方法,该方法使用ADO.NET运行存储过程,以使用上次检查FileSystemWatcher指向的目录的连接日期的日期值来更新DB。

我需要处理进入目录(已创建)的文件,我解析文件名并将其传递给在SqlConnection中使用的方法。

public class FileProcessor
{


    private void HandleFileEvent(object sender, FileSystemEventArgs e)
    {
        CallHandleFileEvent(sender, e);
    }
    private async void CallHandleFileEvent(object sender, FileSystemEventArgs e)
    {
        PartData partData = FileNameParser.ParseFileName(e.Name);
        Log("Event received: {0} Path: {1}", e.ChangeType, e.FullPath);

        Task.Run(() => SqlDataAccess.InsertOrUpdatePartDataInDatabase(partData));
        EventLogger.Log($"Handling file event for partData: {partData.SerialNumber} and the current thread is {Thread.CurrentThread.ManagedThreadId}");
    }


    private void HandleConnectStateChanged(object sender, ConnectionStateChangedEventArgs e)
    {
        CallHandleConnectStateChanged(sender, e);
    }

    private async void CallHandleConnectStateChanged(object sender, ConnectionStateChangedEventArgs e)
    {
        string connectionState = e.ConnectionState.ToString();
        if (connectionState == "Reconnected" || connectionState == "Connected")
        {
            EventLogger.Log($"Attempting to execute UpdateSystemDataLastAccessedAsync for : " +
                            $"{ConfigurationManager.AppSettings["SystemInstanceType"]} - " +
                            $"{ConfigurationManager.AppSettings["SystemInstanceTitle"]} - " +
                            $"{ConfigurationManager.AppSettings["SystemInstanceArea"]}" +
                            $" on thread {Thread.CurrentThread.ManagedThreadId} with a connection state of {e.ConnectionState}");

            Task.Run(() => SqlDataAccess.UpdateSystemDataLastAccessedAsync());

            EventLogger.Log($"Successfully executed UpdateSystemDataLastAccessedAsync for : " +
                            $"{ConfigurationManager.AppSettings["SystemInstanceType"]} - " +
                            $"{ConfigurationManager.AppSettings["SystemInstanceTitle"]} - " +
                            $"{ConfigurationManager.AppSettings["SystemInstanceArea"]}" + 
                            $" on thread {Thread.CurrentThread.ManagedThreadId} with a connection state of {e.ConnectionState}");
        }
    }

    private static void HandleRenameEvent(object sender, RenamedEventArgs e)
    {
        Log("Event received: {0} Path: {1} OldPath: {2}", e.ChangeType, e.FullPath, e.OldFullPath);
    }

    private static void HandleErrorEvent(object sender, ErrorEventArgs e)
    {
        var exception = e.GetException();

        Log("Error received: {0} ({1})", exception.Message, exception.GetType());
    }


    public void Watch(string[] args)
    {
        var checkConnectionInterval = TimeSpan.FromSeconds(Double.Parse(ConfigurationManager.AppSettings["CheckConnectionInterval"])); // Make this a low value for testing!
        var directory = ConfigurationManager.AppSettings["WatchDirectory"];
        var pattern = "*.*";

        var fileSystemWatcher = new NetFileSystemWatcher(checkConnectionInterval, directory, pattern);
        EventLogger.Log("Starting the watcher method");
        // These are the settings we used in our code
        fileSystemWatcher.IncludeSubdirectories = false;
        fileSystemWatcher.NotifyFilter = NotifyFilters.FileName;

        //Subscribe to all events.
        fileSystemWatcher.Created += HandleFileEvent;
        fileSystemWatcher.Error += HandleErrorEvent;

        //Enable the NetFileSystemWatcher events.
        fileSystemWatcher.EnableRaisingEvents = true;

        EventLogger.Log("stopped the watcher method");
    }
    public void ConnectionWatcher(string[] args)
    {
        var checkConnectionInterval = TimeSpan.FromSeconds(Double.Parse(ConfigurationManager.AppSettings["CheckConnectionInterval"])); // Make this a low value for testing!
        var directory = ConfigurationManager.AppSettings["WatchDirectory"];
        var pattern = "*.*";

        var fileSystemWatcher = new NetFileSystemWatcher(checkConnectionInterval, directory, pattern);
        EventLogger.Log("Starting the watcher method");
        // These are the settings we used in our code
        fileSystemWatcher.IncludeSubdirectories = false;
        fileSystemWatcher.NotifyFilter = NotifyFilters.FileName;

        fileSystemWatcher.Error += HandleErrorEvent;
        fileSystemWatcher.ConnectionStateChanged += HandleConnectStateChanged;

        //Enable the NetFileSystemWatcher events.
        fileSystemWatcher.EnableRaisingEvents = true;

        EventLogger.Log("stopped the watcher method");
    }

    public static void Stop()
    {
        // onstop code here
    }

    }
}

此类包含我的两个用于运行存储的proc的ADO方法

public class SqlDataAccess
{
    private static Logger logger = LogManager.GetCurrentClassLogger();

    public static void InsertOrUpdatePartDataInDatabase(PartData partData)
    {
        try
        {
            string connectionString = ConfigurationManager.ConnectionStrings["QMonitorDB"].ToString();
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                EventLogger.Log($"Attempting to execute InsertOrUpdatePartDataInDatabase for serial number: " +
                                $"{partData.SerialNumber} on " +
                                $"{ConfigurationManager.AppSettings["SystemInstanceType"]} - " +
                                $"{ConfigurationManager.AppSettings["SystemInstanceTitle"]} - " +
                                $"{ConfigurationManager.AppSettings["SystemInstanceArea"]}");

                SqlCommand cmd = new SqlCommand("Insert_Or_Update_PartData", conn)
                {
                    CommandType = CommandType.StoredProcedure
                };
                cmd.Parameters.AddWithValue("@applicationInstanceType", ConfigurationManager.AppSettings["ApplicationInstanceType"]);
                cmd.Parameters.AddWithValue("@pdaSerialNumber", partData.SerialNumber);
                cmd.Parameters.AddWithValue("@pdaPartType", partData.PartType);
                cmd.Parameters.AddWithValue("@pdaOperationID", partData.Operation);
                cmd.Parameters.AddWithValue("@pdaTimestamp", (!string.IsNullOrWhiteSpace(partData.TimeStamp) ? partData.TimeStamp : null));
                cmd.Parameters.AddWithValue("@pdaComponent", partData.Component);
                cmd.Parameters.AddWithValue("@pdaFeederSystem", partData.FeederSystemTitle);
                cmd.Parameters.AddWithValue("@pdaFileName", partData.FileName);
                cmd.Parameters.AddWithValue("@pdaStatus", partData.PartStatus);
                conn.Open();
                cmd.ExecuteNonQuery();
                EventLogger.Log($"successfully Executed InsertOrUpdatePartDataInDatabase for serial number: " +
                    $"{partData.SerialNumber} on " +
                    $"{ConfigurationManager.AppSettings["SystemInstanceType"]} - " +
                    $"{ConfigurationManager.AppSettings["SystemInstanceTitle"]} - " +
                    $"{ConfigurationManager.AppSettings["SystemInstanceArea"]}");
            }
        }
        catch (Exception e)
        {
            EventLogger.Log("Error inserting or updating part data into database. Exception: " + e);
            logger.Info($"Unable to insert or update part data in database. Error Message: {e}");
        }
    }

    public static void UpdateSystemDataLastAccessedAsync()
    {
        try
        {
            string connectionString = ConfigurationManager.ConnectionStrings["QMonitorDB"].ToString();
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                EventLogger.Log($"Attempting to execute UpdateSystemDataLastAccessed for " + 
                                $"{ConfigurationManager.AppSettings["SystemInstanceType"]} - " +
                                $"{ConfigurationManager.AppSettings["SystemInstanceTitle"]} - " +
                                $"{ConfigurationManager.AppSettings["SystemInstanceArea"]}");

                SqlCommand cmd = new SqlCommand("Insert_Or_Update_LastAccessed", conn)
                {
                    CommandType = CommandType.StoredProcedure
                };
                cmd.Parameters.AddWithValue("@sdaInstanceType", ConfigurationManager.AppSettings["SystemInstanceType"]);
                cmd.Parameters.AddWithValue("@sdaInstanceName", ConfigurationManager.AppSettings["SystemInstanceTitle"]);
                cmd.Parameters.AddWithValue("@sdaInstanceArea", ConfigurationManager.AppSettings["SystemInstanceArea"]);
                conn.Open();
                cmd.ExecuteNonQuery();
                EventLogger.Log($"Successfully executed UpdateSystemDataLastAccessed for " +
                                $"{ConfigurationManager.AppSettings["SystemInstanceType"]} - " +
                                $"{ConfigurationManager.AppSettings["SystemInstanceTitle"]} - " +
                                $"{ConfigurationManager.AppSettings["SystemInstanceArea"]}");
            }
        }
        catch (Exception e)
        {
            EventLogger.Log("Error updating/inserting system last access in database. Exception: " + e);
            logger.Info($"Unable to update system data into database. Error Message: {e}");
        }
    }
}

这是我的Program.cs,它启动服务并实例化两个FileProcessor实例,一个实例用于处理连接状态更改事件,一个实例用于处理fileWatching事件。

 internal class Program
{
    public static void Main(string[] args)
    {
        EventLog eventLogger = new EventLog();
        eventLogger.Source = "QMonitor-FileMonitor service";
        if (!Environment.UserInteractive)
        {
            // running as service
            using (var service = new Service())
            {
                try
                {
                    ServiceBase.Run(service);
                }
                catch (Exception ex)
                {
                    eventLogger.WriteEntry(ex.Message);
                }
            }
        }
        else
        {
            // running as console app
            //FileProcessor.Watch(args);

            FileProcessor.Stop();
        }
    }
}

public class Service : ServiceBase
{
    public EventLog eventLogger = new EventLog();
    public const string ServiceTitle = "QMonitor-FileMonitor";

    public Service()
    {
        this.CanPauseAndContinue = true;
        this.AutoLog = false;

        eventLogger.Source = ServiceTitle;
        eventLogger.Log = "Application";
    }

    protected override void OnStart(string[] args)
    {
        //Uncomment/comment below to enable/disable service debugging on-start
        //Debugger.Launch();
        try
        {
            EventLogger.Log($"Starting the QMonitor watcher service for: {ConfigurationHelper.GetServiceNameAppConfig("ServiceInstanceTitle", "SystemInstanceTitle", "SystemInstanceArea")}");
            FileProcessor fileProcessor = new FileProcessor();
            FileProcessor connectionFileProcessor = new FileProcessor();
            fileProcessor.Watch(args);
            connectionFileProcessor.ConnectionWatcher(args);
            EventLogger.Log($"Started the QMonitor watcher service for: {ConfigurationHelper.GetServiceNameAppConfig("ServiceInstanceTitle", "SystemInstanceTitle", "SystemInstanceArea")}");
        }
        catch (Exception ex)
        {
            eventLogger.WriteEntry(ex.Message, EventLogEntryType.Error);
        }
        eventLogger.WriteEntry("Exiting the onStart");

    }

    protected override void OnStop()
    {
        eventLogger.WriteEntry("Called on onStop");
        FileProcessor.Stop();
        eventLogger.WriteEntry("onStop completed");
    }
}

这需要异步,触发并忘记(我不等待数据库返回的任何信息)。

0 个答案:

没有答案