我们有一个应用程序将员工W2“打印”为PDF。不幸的是,该应用程序没有密码保护PDF。
我编写了一个使用FileSystemWatcher查找PDF的服务。然后它抓取PDF并使用ASPose.PDF为PDF添加密码和加密。
我的第一个问题是时机。在FileSystemWatcher调用我的事件处理程序通知我新创建的文件之后,我必须在我的代码中嵌入一个Thread.Sleep(2000)。如果我不这样做,我会遇到一个问题,即ASPose.PDF无法获取文件所需的访问权限,因为它正在使用中 - 显然尚未由创建应用程序发布。这是一种有臭味的解决方案,如果有更好的处理方法,我会喜欢一些输入。
但是,我更大的问题是,我希望使用Tasks实现异步处理,以便在生成数千个文件时获得更好的性能。在使用Tasks和线程时,我几乎是个新手。
这是我打算用任务做的......这是正确的做法吗?
public class W2PDFEncryptionService : ServiceBase
{
private FileSystemWatcher _watcher = null;
private Aspose.Pdf.License _license = null;
private string _connectionString = "";
private string _targetDir = "";
private string _masterPassword = "";
private const int SLEEPTIME = 2000;
private const string PASSFORMAT = "[{0}!{1}]";
protected override void OnStart(string[] args)
{
base.OnStart(args);
ReadAppSettings();
//Log current run state
_builder.Clear();
_builder.AppendLine("Sarting Service");
_builder.AppendLine(" Monitor Directory: " + _targetDir);
_builder.AppendLine(" SQL Connection: " + _connectionString);
this.EventLog.WriteEntry(_builder.ToString());
ConfigureFileWatcher();
}
private void ConfigureFileWatcher()
{
// _watcher is a private property of the service
_watcher = new FileSystemWatcher(_targetDir);
_watcher.IncludeSubdirectories = true;
_watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime;
_watcher.Created += new FileSystemEventHandler(OnChanged);
_watcher.Renamed += new RenamedEventHandler(OnRename);
_watcher.EnableRaisingEvents = true;
}
private void OnRename(object sender, RenamedEventArgs e)
{
Task task = ProcessFile(e.FullPath, "PDF Renamed - " + e.OldName + " to " + e.Name + " in folder " + Path.GetDirectoryName(e.FullPath));
}
private void OnChanged(object sender, FileSystemEventArgs e)
{
Task task = ProcessFile(e.FullPath, "PDF Created - " + e.Name + " in folder " + Path.GetDirectoryName(e.FullPath));
}
private async Task ProcessFile(string filename, string logtext)
{
//Pause for two seconds to ensure file is not in use
//Thread.Sleep(SLEEPTIME);
Task.Delay(SLEEPTIME);
EncryptFile(filename, _userPassword); //this is where ASPose.PDF is used
}
这似乎允许服务为创建或重命名的每个PDF启动新的处理/加密任务。
(当然,每个线程都必须创建自己的ASPose.PDF实例,以便处理其文件以避免锁定isuses)
我在这里遗漏了什么?
P.S。正如我已经考虑过这一点,似乎我没有办法考虑暂停或停止使用优秀线程的服务。