我有一个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");
}
}
这需要异步,触发并忘记(我不等待数据库返回的任何信息)。