我已经构建了Windows服务,出于某种原因,当我启动服务时,它会启动,然后立即关闭。我试过谷歌搜索为什么会发生这种情况。任何系统日志中都没有出现任何内容。这是我的服务的开始/停止代码。我希望,因为我已经创建了一个文件监听器,它应该保持运行。我错过了什么?
#region Declarations
private List<string> _keys = new List<string>();
private FileSystemWatcher _watcher;
private BackgroundWorker _worker;
static private bool _isBusy = false;
#endregion
#region Constructor
public FeedListener()
{
InitializeComponent();
}
#endregion
#region Start/Stop
protected override void OnStart(string[] args)
{
_keys.AddRange(new string[] { "csv", "xml", "zip", "rivx" });
_worker = new BackgroundWorker();
_worker.WorkerReportsProgress = true;
_worker.WorkerSupportsCancellation = true;
_worker.DoWork += new DoWorkEventHandler(BackgroundWorkerDoWork);
_worker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorkerProgressChanged);
_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorkerRunWorkerCompleted);
_watcher = new FileSystemWatcher(AppSettings.Default.FTPRootPath, "*.*");
_watcher.IncludeSubdirectories = true;
_watcher.NotifyFilter = sysIO.NotifyFilters.DirectoryName | sysIO.NotifyFilters.FileName | sysIO.NotifyFilters.LastAccess | sysIO.NotifyFilters.CreationTime | sysIO.NotifyFilters.LastWrite;
_watcher.Created += new sysIO.FileSystemEventHandler(fileCreatedOrChanged);
_watcher.Changed += new sysIO.FileSystemEventHandler(fileCreatedOrChanged);
_watcher.EnableRaisingEvents = true;
TouchFiles();
}
protected override void OnStop()
{
_watcher.Dispose();
_watcher = null;
_worker.Dispose();
_worker = null;
}
#endregion
#region Event Handlers
void fileCreatedOrChanged(object sender, sysIO.FileSystemEventArgs e)
{
DTO.BackgroundWorkerEventArgs eventArgs = new DTO.BackgroundWorkerEventArgs();
sysIO.WatcherChangeTypes myType = e.ChangeType;
bool isValid = false;
foreach (string key in _keys)
{
if (Path.GetExtension(e.FullPath).Replace(".", "").Equals(key, StringComparison.CurrentCultureIgnoreCase))
isValid = true;
}
if (isValid)
{
try
{
eventArgs.PathAndFile = e.FullPath;
eventArgs.Key = Path.GetExtension(e.FullPath).ToLower().Replace(".", "");
eventArgs.FileName = Path.GetFileName(e.FullPath);
eventArgs.Path = Path.GetDirectoryName(e.FullPath);
eventArgs.UserName = Path.GetDirectoryName(e.FullPath).Replace(AppSettings.Default.FTPRootPath, "").Replace("\\", "");
FileInfo fileInfo = new FileInfo(eventArgs.PathAndFile);
// 1st attempt at stalling for the file lock due to slow write speeds...
while (IsFileLocked(fileInfo)) { /* nop */ }
// Wait until the thread is not busy...
//while (_worker.IsBusy) { /* nop */ }
while (_isBusy) { /* nop */ }
// Now, spin up a new thread and do the work on the file, based on file type...
_worker.RunWorkerAsync(eventArgs); // goes to BackgroundWorkerDoWork(object sender, DoWorkEventArgs e) //
}
catch (Exception ex)
{
string m = ex.Message;
}
}
}
void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
DTO.BackgroundWorkerEventArgs eventArgs = (DTO.BackgroundWorkerEventArgs)e.Argument;
RivWorks.FeedHandler.Handler handler = new RivWorks.FeedHandler.Handler();
_isBusy = true;
try
{
if (eventArgs.Key.Equals("csv", StringComparison.CurrentCultureIgnoreCase))
{
handler.ImportCSV(ref eventArgs);
}
if (eventArgs.Key.Equals("zip", StringComparison.CurrentCultureIgnoreCase))
{
handler.UnZip(ref eventArgs);
handler.ImportCSV(ref eventArgs);
}
}
catch (Exception ex)
{
string m = ex.Message;
_worker.ReportProgress(0);
}
finally
{
_isBusy = false;
_worker.ReportProgress(100);
if (_worker.CancellationPending)
{
e.Cancel = true;
}
}
}
void BackgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
void BackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
Console.WriteLine("Cancelled.");
}
else if (e.Error != null)
{
Console.WriteLine(e.Error.Message);
}
else
{
Console.WriteLine("Successfully completed.");
}
TouchFiles();
}
#endregion
答案 0 :(得分:4)
我没有看到TouchFiles()的代码,但它听起来像是问题的根源。就像它迭代磁盘驱动器上的所有目录一样。这需要花费很多时间,然后服务控制管理员愿意忍受服务开始(我想30秒)。
启动一个帖子并让它触摸文件。还要注意你的BackgroundWorker,事件是在启动它的同一个线程上调用而不是。这需要一个服务中不可用的同步提供程序。
答案 1 :(得分:2)
为什么不调试它?在Debugger.Break()
方法中添加OnStart
。
答案 2 :(得分:1)
我在您的其他相关帖子中发布了一个答案...我认为问题是您在同一个BackgroundWorker上发起多个RunWorkAsync
来电,这可能会导致该服务崩溃。
此外,您在多线程后台工作程序的上下文中使用_isBusy标志...您需要使用多线程锁定系统,例如Mutex(尽管我仍然说这会破坏运行点BackgroundWorkers异步)。
在此处查看答案:C# based Windows Service - Tries to do JIT Debugging in production
答案 3 :(得分:0)
也许你需要在OnStart的某个地方调用base.OnStart吗?
答案 4 :(得分:0)
我不知道TouchFiles
的作用,但是Windows服务通常在循环eq中运行。 while(true)
,你的似乎没有。
答案 5 :(得分:0)
尝试在OnStart方法的开头添加Debugger.Launch()
行并逐步执行,直到遇到导致问题的异常为止。
另一方面,我会重构设计,因此大部分工作都在一个单独的可测试的类中,只需将服务中的最小部分连接起来。
答案 6 :(得分:0)
看起来你的OnStart只是执行和退出,你没有保持应用程序活着,它就像一个控制台应用程序,开始运行然后退出。如果 这种情况,您需要等待结束/关闭服务事件之类的事情,并让您的工作人员后台线程处理传入的工作请求,而不是退出此例程,直到您的应用程序收到信号通知终止,或许来自一个事件。
答案 7 :(得分:0)
您确定使用的是为您生成的正确服务启动代码吗?如果它只是作为应用程序运行,可能会发生这种情况。当我有一个单独的Main()用于测试时,我发生了这种情况。