C# 在某个事件上崩溃
C# is crashing on an event
我正在尝试将 C# 服务创建为控制台应用程序。
主要代码:
static void Main(string[] args)
{
var exitCode = HostFactory.Run(
x =>
{
x.Service<HeartBeat>(s =>
{
s.ConstructUsing(heartbeat => new HeartBeat());
s.WhenStarted(heartbeat => heartbeat.Start());
s.WhenStopped(heartbeat => heartbeat.Stop());
});
x.RunAsLocalSystem();
x.SetServiceName("UpgradeServices");
x.SetDisplayName("Service Upgrade");
x.SetDescription("Service is monitoring new version.");
});
int exitCodeValue = (int)Convert.ChangeType(exitCode, exitCode.GetTypeCode());
Environment.ExitCode = exitCodeValue;
}
然后我有删除和复制文件的代码如下:
public class MovingFiles
{
public string fileName;
public string destPath;
private DirectoryInfo directory;
private DirectoryInfo myFile;
public string sourcePath;
public string targetPath;
public MovingFiles(string sourceFolder, string targetFolder)
{
sourcePath = sourceFolder;
targetPath = targetFolder;
}
public void deleteFilesMethod()
{
System.Threading.Thread.Sleep(10000);
string deleteString;
//First we want to delete all files except for the JSON file as this has all of the important settings
if (System.IO.Directory.Exists(targetPath))
{
string[] files = System.IO.Directory.GetFiles(targetPath);
// Loop through each files and then delete these if they are not the JSON file
foreach (string s in files)
{
deleteString = targetPath;
// The file name which is returned will be deleted
fileName = System.IO.Path.GetFileName(s);
if (fileName != "appsettings.json")
{
deleteString = System.IO.Path.Combine(targetPath, fileName);
try
{
System.IO.File.Delete(deleteString);
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
return;
}
}
}
}
else
{
Console.WriteLine("The loop didn't run, source path doesn't exist");
}
}
public void copyFilesMethod()
{
System.Threading.Thread.Sleep(10000);
if (System.IO.Directory.Exists(sourcePath))
{
// Searching for the latest directory created in the sourcePath folder
directory = new DirectoryInfo(sourcePath);
myFile = (from f in directory.GetDirectories()
orderby f.LastWriteTime descending
select f).First();
sourcePath = System.IO.Path.Combine(sourcePath, myFile.Name);
string[] files = System.IO.Directory.GetFiles(sourcePath);
// Copy the files and overwrite destination files if they already exist.
foreach (string s in files)
{
// Use static Path methods to extract only the file name from the path.
fileName = System.IO.Path.GetFileName(s);
if (fileName != "appsettings.json")
{
destPath = System.IO.Path.Combine(targetPath, fileName);
try
{
System.IO.File.Copy(s, destPath, true);
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
return;
}
}
}
}
else
{
Console.WriteLine("The loop didn't run, source path doesn't exist");
}
// Keep console window open in debug mode.
Console.WriteLine("Procedure has been completed.");
}
一旦有一个新文件就会触发,我是这样写的:
class FileMonitor
{
public FileSystemWatcher watcher = new FileSystemWatcher();
public string sourcePath;
public string targetPath;
public FileMonitor(string sourceFolder, string targetFolder)
{
sourcePath = sourceFolder;
targetPath = targetFolder;
}
public void watch()
{
watcher.Path = sourcePath;
watcher.NotifyFilter = NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName
| NotifyFilters.CreationTime;
//var one = NotifyFilters.FileName;
watcher.Filter = "*.*";
watcher.Created += new FileSystemEventHandler (OnChanged);
watcher.EnableRaisingEvents = true;
//System.Threading.Thread.Sleep(25000);
}
public void OnChanged(object source, FileSystemEventArgs e)
{
//Copies file to another directory.
MovingFiles FileMoveOne = new MovingFiles(sourcePath, targetPath);
FileMoveOne.deleteFilesMethod();
FileMoveOne.copyFilesMethod();
}
}
我在运行下面的理解是,如果有新文件,它会每 10 秒查看一次,然后触发 OnChange 方法,对吗?
public class HeartBeat
{
private readonly Timer _timer;
public HeartBeat()
{
_timer = new Timer(10000)
{
AutoReset = true
};
_timer.Elapsed += TimerElapsed;
}
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
//StringBuilder loggingLine = new StringBuilder();
/* Every 30 seconds it will write to the file */
string[] lines = new string[] {DateTime.Now.ToString() + ": Heartbeat is active. Service is monitoring SS and DS"};
//lines[1] = DateTime.Now.ToString() + " About to check if new files are placed on server";
//loggingLine.Append(lines[i]);
File.AppendAllLines(@"C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor1\HeartBeat.log", lines);
//File.AppendAllLines(@"C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor1\HeartBeat.log", lines);
FileMonitor versioOne = new FileMonitor(@"C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor1", @"C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor2");
versioOne.watch();
}
public void Start ()
{
_timer.Start();
}
public void Stop ()
{
_timer.Stop();
}
}
我遇到的问题是不一致。
创建新文件夹后,它应该将文件复制到文件夹 Monitor2,但在第一次创建时并没有这样做。一旦在 monitor1 文件夹中创建文件夹,它就会第二次删除和复制文件。
它每隔一秒尝试复制文件时崩溃,并出现以下我不熟悉的错误:
Topshelf.Hosts.ConsoleRunHost Critical: 0 : The service threw an unhandled exception, System.UnauthorizedAccessException: Access to the path 'C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor2\System.Net.Sockets.dll' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalDelete(String path, Boolean checkHost)
at System.IO.File.Delete(String path)
at UpgradeServices.MovingFiles.deleteFilesMethod() in C:\Users\RLEBEDEVS\Desktop\C#\Service\UpgradeServices\MovingFIles.cs:line 48
at UpgradeServices.FileMonitor.OnChanged(Object source, FileSystemEventArgs e) in C:\Users\RLEBEDEVS\Desktop\C#\Service\UpgradeServices\FileMonitor.cs:line 43
at System.IO.FileSystemWatcher.OnCreated(FileSystemEventArgs e)
at System.IO.FileSystemWatcher.NotifyFileSystemEventArgs(Int32 action, String name)
at System.IO.FileSystemWatcher.CompletionStatusChanged(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* overlappedPointer)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
Topshelf.Hosts.ConsoleRunHost Information: 0 : Stopping the UpgradeServices service
Topshelf.Hosts.ConsoleRunHost Information: 0 : The UpgradeServices service has stopped.
The program '[497452] UpgradeServices.exe' has exited with code 1067 (0x42b).
第 48 行就是这一行,尽管它执行了之前的任务(第一次)。
System.IO.File.Delete(deleteString);
我发现问题出在我发起活动的方式上。有谁知道我应该更改什么以达到预期的结果,即当服务在命运中创建的每个新文件夹上启动时,它将执行移动和删除文件的两种方法?该文件夹将始终只创建新文件夹。
此致,
似乎在你的心跳中你每 10 秒开始新的 FileMonitor
,所以 20 秒后你将有 2 FileMonitor
同时观看和移动(删除)相同的文件.例如,只需使用 hosted service 开始 FileMonitor
一次。或者删除 HeartBeat
class 中的计时器处理程序部分,然后在构造函数中创建 FileMonitor
:
public HeartBeat()
{
FileMonitor versioOne = new
FileMonitor(@"C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor1", @"C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor2");
versioOne.watch();
// may be save it to instance field so it does not get garbage collected.
// Not sure how FileSystemWatcher behaves with subscription,
// it should prevent the "versionOne" from being collected via subscription.
}
我正在尝试将 C# 服务创建为控制台应用程序。
主要代码:
static void Main(string[] args)
{
var exitCode = HostFactory.Run(
x =>
{
x.Service<HeartBeat>(s =>
{
s.ConstructUsing(heartbeat => new HeartBeat());
s.WhenStarted(heartbeat => heartbeat.Start());
s.WhenStopped(heartbeat => heartbeat.Stop());
});
x.RunAsLocalSystem();
x.SetServiceName("UpgradeServices");
x.SetDisplayName("Service Upgrade");
x.SetDescription("Service is monitoring new version.");
});
int exitCodeValue = (int)Convert.ChangeType(exitCode, exitCode.GetTypeCode());
Environment.ExitCode = exitCodeValue;
}
然后我有删除和复制文件的代码如下:
public class MovingFiles
{
public string fileName;
public string destPath;
private DirectoryInfo directory;
private DirectoryInfo myFile;
public string sourcePath;
public string targetPath;
public MovingFiles(string sourceFolder, string targetFolder)
{
sourcePath = sourceFolder;
targetPath = targetFolder;
}
public void deleteFilesMethod()
{
System.Threading.Thread.Sleep(10000);
string deleteString;
//First we want to delete all files except for the JSON file as this has all of the important settings
if (System.IO.Directory.Exists(targetPath))
{
string[] files = System.IO.Directory.GetFiles(targetPath);
// Loop through each files and then delete these if they are not the JSON file
foreach (string s in files)
{
deleteString = targetPath;
// The file name which is returned will be deleted
fileName = System.IO.Path.GetFileName(s);
if (fileName != "appsettings.json")
{
deleteString = System.IO.Path.Combine(targetPath, fileName);
try
{
System.IO.File.Delete(deleteString);
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
return;
}
}
}
}
else
{
Console.WriteLine("The loop didn't run, source path doesn't exist");
}
}
public void copyFilesMethod()
{
System.Threading.Thread.Sleep(10000);
if (System.IO.Directory.Exists(sourcePath))
{
// Searching for the latest directory created in the sourcePath folder
directory = new DirectoryInfo(sourcePath);
myFile = (from f in directory.GetDirectories()
orderby f.LastWriteTime descending
select f).First();
sourcePath = System.IO.Path.Combine(sourcePath, myFile.Name);
string[] files = System.IO.Directory.GetFiles(sourcePath);
// Copy the files and overwrite destination files if they already exist.
foreach (string s in files)
{
// Use static Path methods to extract only the file name from the path.
fileName = System.IO.Path.GetFileName(s);
if (fileName != "appsettings.json")
{
destPath = System.IO.Path.Combine(targetPath, fileName);
try
{
System.IO.File.Copy(s, destPath, true);
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
return;
}
}
}
}
else
{
Console.WriteLine("The loop didn't run, source path doesn't exist");
}
// Keep console window open in debug mode.
Console.WriteLine("Procedure has been completed.");
}
一旦有一个新文件就会触发,我是这样写的:
class FileMonitor
{
public FileSystemWatcher watcher = new FileSystemWatcher();
public string sourcePath;
public string targetPath;
public FileMonitor(string sourceFolder, string targetFolder)
{
sourcePath = sourceFolder;
targetPath = targetFolder;
}
public void watch()
{
watcher.Path = sourcePath;
watcher.NotifyFilter = NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName
| NotifyFilters.CreationTime;
//var one = NotifyFilters.FileName;
watcher.Filter = "*.*";
watcher.Created += new FileSystemEventHandler (OnChanged);
watcher.EnableRaisingEvents = true;
//System.Threading.Thread.Sleep(25000);
}
public void OnChanged(object source, FileSystemEventArgs e)
{
//Copies file to another directory.
MovingFiles FileMoveOne = new MovingFiles(sourcePath, targetPath);
FileMoveOne.deleteFilesMethod();
FileMoveOne.copyFilesMethod();
}
}
我在运行下面的理解是,如果有新文件,它会每 10 秒查看一次,然后触发 OnChange 方法,对吗?
public class HeartBeat
{
private readonly Timer _timer;
public HeartBeat()
{
_timer = new Timer(10000)
{
AutoReset = true
};
_timer.Elapsed += TimerElapsed;
}
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
//StringBuilder loggingLine = new StringBuilder();
/* Every 30 seconds it will write to the file */
string[] lines = new string[] {DateTime.Now.ToString() + ": Heartbeat is active. Service is monitoring SS and DS"};
//lines[1] = DateTime.Now.ToString() + " About to check if new files are placed on server";
//loggingLine.Append(lines[i]);
File.AppendAllLines(@"C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor1\HeartBeat.log", lines);
//File.AppendAllLines(@"C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor1\HeartBeat.log", lines);
FileMonitor versioOne = new FileMonitor(@"C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor1", @"C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor2");
versioOne.watch();
}
public void Start ()
{
_timer.Start();
}
public void Stop ()
{
_timer.Stop();
}
}
我遇到的问题是不一致。
创建新文件夹后,它应该将文件复制到文件夹 Monitor2,但在第一次创建时并没有这样做。一旦在 monitor1 文件夹中创建文件夹,它就会第二次删除和复制文件。
它每隔一秒尝试复制文件时崩溃,并出现以下我不熟悉的错误:
Topshelf.Hosts.ConsoleRunHost Critical: 0 : The service threw an unhandled exception, System.UnauthorizedAccessException: Access to the path 'C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor2\System.Net.Sockets.dll' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalDelete(String path, Boolean checkHost)
at System.IO.File.Delete(String path)
at UpgradeServices.MovingFiles.deleteFilesMethod() in C:\Users\RLEBEDEVS\Desktop\C#\Service\UpgradeServices\MovingFIles.cs:line 48
at UpgradeServices.FileMonitor.OnChanged(Object source, FileSystemEventArgs e) in C:\Users\RLEBEDEVS\Desktop\C#\Service\UpgradeServices\FileMonitor.cs:line 43
at System.IO.FileSystemWatcher.OnCreated(FileSystemEventArgs e)
at System.IO.FileSystemWatcher.NotifyFileSystemEventArgs(Int32 action, String name)
at System.IO.FileSystemWatcher.CompletionStatusChanged(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* overlappedPointer)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)Topshelf.Hosts.ConsoleRunHost Information: 0 : Stopping the UpgradeServices service
Topshelf.Hosts.ConsoleRunHost Information: 0 : The UpgradeServices service has stopped.The program '[497452] UpgradeServices.exe' has exited with code 1067 (0x42b).
第 48 行就是这一行,尽管它执行了之前的任务(第一次)。
System.IO.File.Delete(deleteString);
我发现问题出在我发起活动的方式上。有谁知道我应该更改什么以达到预期的结果,即当服务在命运中创建的每个新文件夹上启动时,它将执行移动和删除文件的两种方法?该文件夹将始终只创建新文件夹。
此致,
似乎在你的心跳中你每 10 秒开始新的 FileMonitor
,所以 20 秒后你将有 2 FileMonitor
同时观看和移动(删除)相同的文件.例如,只需使用 hosted service 开始 FileMonitor
一次。或者删除 HeartBeat
class 中的计时器处理程序部分,然后在构造函数中创建 FileMonitor
:
public HeartBeat()
{
FileMonitor versioOne = new
FileMonitor(@"C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor1", @"C:\Users\RLEBEDEVS\Desktop\Monitor\Monitor2");
versioOne.watch();
// may be save it to instance field so it does not get garbage collected.
// Not sure how FileSystemWatcher behaves with subscription,
// it should prevent the "versionOne" from being collected via subscription.
}