我有一个处理文件的服务。有时它们处理得非常快,有时它们需要很长时间。我无法控制将文件发送给我的过程。在白天和晚上随机掉落在我身上。当我使用计时器时,它似乎是" ProcessFiles"当时间结束并且再次调用ProcessFiles时,方法被放弃。由于文件包含敏感信息,因此他们无法长时间坐在服务器上,因此我无法将计时器设置为超过5分钟,并且仍然在5分钟时,该过程有时会中断自身。结果,我有部分处理过的文件。我很感激任何有关这一困境的想法和意见。
System.Timers.Timer _timer;
// As the files come in, massage them and encrypt them
public const string InPath = @"c:\input";
public const string OutPath = @"\c:\output";
public FileMassaging()
{
InitializeComponent();
}
public EventLog MyEventLog = new EventLog();
public string sSource = "FileMassaging";
public string sLog = "FileMassaging";
protected override void OnStart(string[] args)
{
// Create the source, if it does not already exist.
if (!EventLog.SourceExists(sSource))
EventLog.CreateEventSource(sSource, sLog);
// set up the service
ServiceStatus serviceStatus = new ServiceStatus();
serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING;
serviceStatus.dwWaitHint = 100000;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
// set up the service
_timer = new System.Timers.Timer();
_timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
_timer.Interval = 5000;
_timer.Start();
// Update the service state to Running.
serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
}
public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
ProcessFiles();
}
public void ProcessFiles()
{
string[] originalFiles = Directory.GetFiles(InPath + @"\", "*.txt");
foreach (string fileName in originalFiles)
{
// Check and process the file
CheckFile(InPath, OutPath, fileName);
}
}
public void CheckFile(string InPath,Outpath, fileName)
{
// for example only -- actual file processing is much longer
//
string infile = InPath+fileName;
string outfile= OutPath+fileName;
File.Move(infile,outfile,true);
}
答案 0 :(得分:1)
从定时器上的MSDN页面尝试此操作(https://msdn.microsoft.com/en-us/library/system.timers.timer.interval(v=vs.110).aspx)
_timer = new System.Timers.Timer(5);
_timer.Elapsed += OnTimer;
_timer.AutoReset = true;
// _timer.Start();
_timer.Enable = true;
private static void OnTimer(object sender, System.Timers.ElapsedEventArgs args) { ProcessFiles(); }
答案 1 :(得分:1)
对于测试和可扩展性,我建议使用不同的整体结构。
首先让我们将这项工作分成有意义的课程。让我们从一个名为FolderWatcher的类开始:
public class FolderWatcher
{
private readonly string _inPath;
private readonly string _outPath;
public bool CurrentlyRunning { get; set; }
public FolderWatcher(string inPath, string outPath)
{
_inPath = inPath;
_outPath = outPath;
}
public void TryProcessFiles(object sender, ElapsedEventArgs e)
{
try
{
this.CurrentlyRunning = true;
ProcessFiles(sender, e);
}
catch (Exception)
{
throw;
}
finally
{
this.CurrentlyRunning = false;
}
}
public void ProcessFiles(object sender, ElapsedEventArgs e)
{
string[] originalFiles = GetFilesInDirectory();
foreach (var originalFile in originalFiles)
{
CheckFile(originalFile);
}
}
// Internal/Virtual so that this can mocked in unit testing.
internal virtual string[] GetFilesInDirectory()
{
return Directory.GetFiles(_inPath + @"\", "*.txt");
}
// Internal/Virtual so that this can mocked in unit testing.
internal virtual void CheckFile(string fileName)
{
string infile = $"{_inPath}{fileName}";
string outfile = $"{_outPath}{fileName}";
File.Move(infile, outfile);
}
}
此类只负责移动文件以响应事件。
接下来让我们构建一个类来包装处理计时器功能的FolderWatcher类:
public class TimedFolderWatcher
{
private readonly FolderWatcher _folderWatcher;
private readonly Timer _timer;
public TimedFolderWatcher(FolderWatcher folderWatcher)
{
_folderWatcher = folderWatcher;
InitTimer();
}
private void InitTimer()
{
_timer.Elapsed += new System.Timers.ElapsedEventHandler(this.ProcessFiles);
_timer.Interval = 5000;
_timer.Start();
}
private void ProcessFiles(object sender, ElapsedEventArgs e)
{
_folderWatcher.TryProcessFiles(sender, e);
}
}
这个类也有责任每5000毫秒调用一次ProcessFiles方法。
最后,我们可以通过这种方式初始化并调用这些类:
var fileMassageService = new TimedFolderWatcher(new FolderWatcher(@"c:\input", @"c:\output"));
这种方法有助于测试并遵循依赖注入的最佳实践,如果需要,将来可以使用IOC框架。