繁体   English   中英

单独线程上的 FileSystemWatcher

[英]FileSystemWatcher on separate thread

我必须创建脚本,它将一些文件推送到提供的位置并获取其他脚本生成的 output。

  1. 将文件复制到位置。
  2. 其他脚本将抓取文件并处理它们。
  3. 等待所有结果。
  4. 从文件中获取数据,删除文件。
  5. 对下一组文件重复这些步骤。

在我的 PC 上一切正常,但是当我在 Windows Server 2016 运行的机器上运行我的脚本时,会弹出一些错误: 在此处输入图像描述

所以我创建了一个 SystemWatcher 来监控提供的位置

    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    private void RunWatcher(string location)
    {
        // Create a new FileSystemWatcher and set its properties.
        using (FileSystemWatcher watcher = new FileSystemWatcher())
        {
            watcher.Path = location;

            // Watch for changes in LastAccess and LastWrite times, and
            // the renaming of files or directories.
            watcher.NotifyFilter = NotifyFilters.LastAccess
                                | NotifyFilters.LastWrite
                                | NotifyFilters.FileName
                                | NotifyFilters.DirectoryName;

            watcher.Filter = "*";

            // Add event handlers.
            watcher.Created += OnCreate;

            // Begin watching.
            watcher.EnableRaisingEvents = true;

            // quit the program.
            while (!endWatcher);
        }
    }
    private void OnCreate(object source, FileSystemEventArgs e)
    { 
        string fileExtension = Path.GetExtension(e.FullPath);
        if (extensionWatch.Contains(fileExtension))
        {
            SaveFileData(fileExtension, e.FullPath);
        }
    }

观察者是在单独的线程上创建的。 然后“for”中的“while”循环检查是否所有文件都已创建或是否已超过“放弃时间”。

    private void PushFiles(string destinationPath, int timeAbandon, BackgroundWorker worker)
    {
        Console.WriteLine("Before start watcher");
        Task.Run(() =>
        {
            RunWatcher(destinationPath);
        });    
        Console.WriteLine("After start watcher");
        timeAbandon *= 60; // to sec
        
        for (int i = 0; i < fileCollect.Count; i++)
        {
            double timeDiff;
            start = DateTime.UtcNow;
            currentListIdx = i;
            CopyPtx(fileCollect[i], destinationPath);
            while (!CheckIfDone(i))
            {
                timeDiff = (DateTime.UtcNow - start).TotalSeconds;
                if (timeDiff > timeAbandon)
                {
                    break;
                }
                Thread.Sleep(1000);
                Console.WriteLine("Waiting for results...");
            }
            CopyAndRemoveFiles(fileCollect[i], destinationPath);
            worker.ReportProgress(1);
        }
        endWatcher = true;
    }

    private bool CheckIfDone(int stackId)
    {
        bool isDone = true;
        foreach (var file in fileCollect[stackId])
        {
            if (file["finished"] == "false")
            {
                isDone = false;
            }
        }
        if (isDone)
        {
            return true;
        }
        return false;
    }

我确实查看了即时设置并选择了“托管、本机、脚本”。 我也使用 .net Core,因为我无法在服务器机器上安装任何依赖项。

要在服务器上运行脚本,我首先使用以下设置发布脚本: 在此处输入图像描述 我尝试将配置设置更改为“Debug|AnyCPU”,但没有帮助。

谁能帮我获取有关该错误的更多信息? 或者可能解决我的问题?

function SaveFileData(fileExtension, e.FullPath); . 出现错误是因为我试图在保存到文件完成之前读取文件。 所以这篇文章的标题是不正确的。

为了解决访问文件的问题,我使用了以下代码。

    protected virtual bool IgnoreErrorMsg(FileInfo file, string ignoreMsg)
    {
        bool isAccess = false;

        while (!isAccess)
        {
            try
            {
                using (FileStream stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None))
                {
                    //if file can be read, then read it
                    if (stream.CanRead)
                    {
                        byte[] buffer = new byte[stream.Length];
                        int bytesRead = stream.Read(buffer, 0, buffer.Length);
                        string errorString = Encoding.ASCII.GetString(buffer, 0, bytesRead);

                        if (errorString.Contains(ignoreMsg))
                        {
                            return true;
                        }
                        // access has been granted so loop can be exit
                        isAccess = true;
                    }
                    stream.Close();
                }
            }
            catch (IOException e)
            {
                //the loop will continue as long as "cannot access" error appear
                isAccess = false;
            }
            Thread.Sleep(500);
        }
        //if return false, then script will wait for optimisation unitil AbandonTime
        return false;
    }

在这种情况下,帖子的标题不正确,因为它与多线程无关。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM