FileSystemWatcher线程和计时问题

时间:2014-11-12 17:31:51

标签: c# multithreading

我们有一个应用程序将员工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。正如我已经考虑过这一点,似乎我没有办法考虑暂停或停止使用优秀线程的服务。

0 个答案:

没有答案