创建队列以处理由FileSystemWatcher触发的作业

时间:2012-11-16 04:58:21

标签: c# windows winforms queue filesystemwatcher

我已经构建了一个小托盘应用程序,它将观察文件夹,当添加新文件时,它会运行一个作业。我们的工作是观察视频文件并使用handBrakeCli将它们转换为.mp4。我已经解决了所有这些逻辑。我遇到的问题是,如果有多个文件,我希望它将作业排队,直到前一个完成。我对c#相当新,我不确定处理这个问题的最佳方法。

一个想法是以某种方式创建一个队列,一个文件按顺序存储命令,然后在该过程完成后执行下一个。我们在这里处理大型电影文件,因此可能需要一段时间。我在具有8GB内存的四核上执行此操作,通常需要大约30分钟才能完成一部完整的电影。我只是不知道该怎么做。

这是我到目前为止的代码。这里有一些用于未来功能的位,所以它指的是你不会看到的一些类,但它并不重要,因为它们在这里没有使用。欢迎任何建议。

    public void Watcher()
    {
        FileSystemWatcher watcher = new FileSystemWatcher();

        watcher.Path = textBox1.Text + "\\"; //path to watch
        watcher.Filter = strfilter; //what types to look for set to * and i will filter later as it cant accept an array
        watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName; //properties to look at
        watcher.IncludeSubdirectories = true; //scan subdirs
        watcher.Created += new FileSystemEventHandler(OnChanged);

        //TODO: make this only run if the files are of a certain type
        watcher.EnableRaisingEvents = true; // start the watcher
    }

    static bool IsFileLocked(FileInfo file)
    {
        FileStream stream = null;

        try
        {
            stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
        }
        catch (IOException)
        {
            //the file is unavailable because it is:
            //still being written to
            //or being processed by another thread
            //or does not exist (has already been processed)
            return true;
        }
        finally
        {
            if (stream != null)
                stream.Close();
        }

        //file is not locked
        return false;
    }

    // Define the event handlers. 
    private void OnChanged(object source, FileSystemEventArgs e)
    {
        string sFile = e.FullPath;
        //check that file is available
        FileInfo fileInfo = new FileInfo(sFile);
        while (IsFileLocked(fileInfo))
        {
            Thread.Sleep(500);
        }

        if (System.Diagnostics.Process.GetProcessesByName("HandBrakeCLI").Length != 0)
        {
            Thread.Sleep(500);
        }
        else
        {
            //hbOptions hbCl = new hbOptions();
            //hbCli = hbCl.HbCliOptions();
            if (textBox3.Text != "")
            {
                hbCli = textBox3.Text.ToString();
            }
            else
            {
                hbCli = "-e x264 -q 20 -B 160";
            }
            string t = e.Name;
            string s = t.Substring(0, t.Length - 4); //TODO: fix this its not reliable
            file = e.FullPath;
            string opath = textBox1.Text.ToString();
            cmd = "-i \"" + file + "\" -o \"" + opath + "\\" + s + ".mp4\" " + hbCli;

            try
            {
                for (int i = 0; i < Ext.Count(); i++)
                {
                    if (e.Name.Contains(Ext[i]))
                    {
                        Process hb = new Process();
                        hb.StartInfo.FileName = "D:\\Apps\\Handbrake\\Install\\Handbrake\\HandBrakeCLI.exe";
                        hb.StartInfo.Arguments = cmd;

                        notifyIcon.BalloonTipTitle = "Now Converting";
                        notifyIcon.BalloonTipText = file;
                        notifyIcon.ShowBalloonTip(2000);

                        hb.Start();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }

    private void button1_Click(object sender, EventArgs e) //ok button
    {
        //add each array item to the list 
        for (int i = 0; i < filter.Count(); i++)
        {
            Ext.Add(filter[i]);
        }

        if (textBox1.Text != "" && textBox1.Text.Length > 2)
        {
            Watcher(); //call watcher to run
        }

        this.WindowState = FormWindowState.Minimized;
    }
}

1 个答案:

答案 0 :(得分:0)

您想要使用WCF和MsmqQueueBinding:

  • 服务使用NetMsmqBinding
  • 使用内置到Windows队列MSMQ为您实现的队列(您可以使用MMC snap-it来控制主,死和中毒字母队列。客户端和服务器Windows操作系统都捆绑在一起,转向它在Windows Features
  • 客户端将进程请求放入队列并忘记它
  • 服务自动接收并处理
  • 队列是持久的,持久的和交易的(如果你想要的话)
  • 您可以在同一台计算机或另一台Intranet服务器上运行队列

请参阅以下精彩教程: