基于 FileSystemWatcher 事件显示表单

Displaying form based on FileSystemWatcher event

我正在为教育目的创建一个 windows 表单应用程序,它的基本想法是有一个下载管理器,它将文件从默认下载文件夹移动到文件扩展名的文件夹。我创建了 class MyFileWatcher,它基本上监视新文件的下载文件夹,代码如下所示:

public class MyFileWatcher
    {
        private readonly FileSystemWatcher _fileSystemWatcher;

        public MyFileWatcher()
        {

            _fileSystemWatcher = new FileSystemWatcher(resources.sourcePath);
            _fileSystemWatcher.Created += (sender, e) => _fileWatcher_Created(sender, e);

            _fileSystemWatcher.EnableRaisingEvents = true;
        }

        private void _fileWatcher_Created(object sender, FileSystemEventArgs e)
        {
            //calls class FileManager's function MoveFiles (here is base logic of how and where files should move)
            CustomServiceContainer.GetService<IFileManager>().MoveFiles(resources.sourcePath, resources.targetPath);

            //this is the problem
            Notification_form ntf = new Notification_form();
            ntf.showAlert(eventType);
        }
    }

问题是,当 _fileWatcher_Created 事件调用通知表单时,什么也没有显示(即使我认为我可以在任务栏上看到创建了 window)而且我不明白为什么,因为如果我将 showAlert 函数分配给按钮的单击事件,它会正确显示通知。

如果需要,这就是通知表单的样子:

public partial class Notification_form : Form
    {
        private int x { get; set; }
        private int y { get; set; }

        public Notification_form()
        {
            InitializeComponent();
        }

        public enum enmAction { wait, start, close }

        private Notification_form.enmAction action;

        public void showAlert(string msg)
        {
            this.Opacity = 0.0;
            this.StartPosition = FormStartPosition.Manual;
            string fName;

            for (int i = 1; i < 10; i++)
            {
                fName = "alert" + i.ToString();
                Notification_form frm = (Notification_form)Application.OpenForms[fName];

                if (frm == null)
                {
                    this.Name = fName;
                    this.x = Screen.PrimaryScreen.WorkingArea.Width - this.Width + 15;
                    this.y = Screen.PrimaryScreen.WorkingArea.Height - this.Height * i;
                    this.Location = new Point(this.x, this.y);
                    break;
                }
            }

            this.x = Screen.PrimaryScreen.WorkingArea.Width - base.Width - 5;

            this.lblTitle.Text = msg;

            this.Show();
            this.action = enmAction.start;
            this.timer1.Interval = 1;
            this.timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            switch (this.action)
            {
                case enmAction.wait:
                    timer1.Interval = 5000;
                    action = enmAction.close;
                    break;
                case Notification_form.enmAction.start:
                    this.timer1.Interval = 1;
                    this.Opacity += 0.1;
                    if (this.x < this.Location.X)
                    {
                        this.Left--;
                    }
                    else
                    {
                        if (this.Opacity == 1.0)
                        {
                            action = Notification_form.enmAction.wait;
                        }
                    }
                    break;
                case enmAction.close:
                    timer1.Interval = 1;
                    this.Opacity -= 0.1;

                    this.Left -= 3;
                    if (base.Opacity == 0.0)
                    {
                        base.Close();
                    }
                    break;
            }
        }

        private void btnCloseNtf_Click(object sender, EventArgs e)
        {
            timer1.Interval = 1;
            action = enmAction.close;
        }
    }

对于那些遇到同样问题的人,正如 Jimi 所说,在这种情况下的主要问题是 UI 和 FileSystemWatcher 在不同的线程上工作,所以当我尝试从 MyFileWatcher 调用表单时它没有'由于调用是从不同的线程进行的,因此无法显示表单,我该如何解决?好吧,我在 Form 中设置了 FileSystemWatcher 的 SynchronizingObject(所有学分归于 Jimi),如下所示: fw._fileSystemWatcher.SynchronizingObject = this; 其中 fw 是 FileSystemWatcher 对象,它在从 Program class [=18 创建过程中传递给表单=](注意:在这种情况下,传递以形成您将用于获取通知的同一对象很重要)。

此外,创建文件并不意味着可以移动文件(正如吉米所说,再次:))。通常文件在下载期间处于临时扩展状态(tmp、crdownload 或什至其他),因此您还需要检查文件更改以确保您没有移动没有价值的临时文件,除此之外,在创建文件时并更改通知表单被多次调用,甚至认为我需要它触发一次,因为在现实中创建了一个文件。那么我该如何解决呢?好吧,我不知道它是否是最好的解决方案,但我创建了一个新的文本文档,其中包含我想要移动的所有扩展类型,所以现在我正在检查下载文件夹以查找我的文本文档中的扩展,如果我们匹配文件被移动,因为我不再寻找临时文件类型,FileSystemWatcher 现在实际上给了我一个通知。 (如果需要,您始终可以在文本文档中手动添加新文件类型,但我打算将该功能集成到应用程序中)

希望这对某人有所帮助,有一天...