3

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

一个想法是以某种方式创建一个队列,一个用于按顺序存储命令的文件,然后在该过程完成后执行下一个。我们在这里处理大型电影文件,因此可能需要一段时间。我在具有 8GB RAM 的四核上执行此操作,完成一部完整的电影似乎通常需要大约 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;
    }
}
4

1 回答 1

0

您想利用 WCF 和 MsmqQueueBinding:

  • 服务使用NetMsmqBinding
  • 使用内置在 Windows 队列中的称为MSMQ的队列为您实现(您可以使用 MMC snap-it 来控制主要、死信和毒信队列。客户端和服务器 Windows 操作系统都与它捆绑在一起,在Windows 功能中打开它)
  • 客户端将进程请求放入队列并忘记它
  • 服务自动接收并处理
  • 队列是持久的、持久的和事务性的(如果你愿意的话)
  • 您可以在同一台机器或另一台 Intranet 服务器上运行队列

请参阅以下精彩教程:

于 2012-11-16T05:05:06.257 回答