C# 基于FileSystemWatcher事件显示表单

C# 基于FileSystemWatcher事件显示表单,c#,winforms,file-watcher,C#,Winforms,File Watcher,我正在创建一个用于教育目的的windows窗体应用程序,它的基本思想是有一个下载管理器,可以将文件从默认下载文件夹移动到名为files extension的文件夹。我创建了MyFileWatcher类,它主要监视下载文件夹中的新文件,代码如下所示: public class MyFileWatcher { private readonly FileSystemWatcher _fileSystemWatcher; public MyFileWatcher

我正在创建一个用于教育目的的windows窗体应用程序,它的基本思想是有一个下载管理器,可以将文件从默认下载文件夹移动到名为files extension的文件夹。我创建了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);
        }
    }
公共类MyFileWatcher
{
私有只读FileSystemWatcher\u FileSystemWatcher;
公共MyFileWatcher()
{
_fileSystemWatcher=新的fileSystemWatcher(resources.sourcePath);
_fileSystemWatcher.Created+=(发送方,e)=>\u fileWatcher\u Created(发送方,e);
_fileSystemWatcher.EnableRaisingEvents=true;
}
私有void\u fileWatcher\u已创建(对象发送方、文件系统管理员)
{
//调用类FileManager的函数MoveFiles(以下是文件移动方式和位置的基本逻辑)
CustomServiceContainer.GetService().MoveFiles(resources.sourcePath,resources.targetPath);
//这就是问题所在
通知表单ntf=新通知表单();
ntf.showAlert(事件类型);
}
}
问题是,当_fileWatcher _创建事件调用通知表单时,没有显示任何内容(即使我可以在任务栏上看到创建的窗口),我也不知道为什么,因为如果我将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;
        }
    }

公共部分类通知\u表单:表单
{
私有int x{get;set;}
私有int y{get;set;}
公告表格(
{
初始化组件();
}
公共枚举操作{等待,启动,关闭}
私人通知形式的授权行动;
公共void showAlert(字符串消息)
{
不透明度=0.0;
this.StartPosition=FormStartPosition.Manual;
字符串fName;
对于(int i=1;i<10;i++)
{
fName=“警报”+i.ToString();
通知表单frm=(通知表单)应用程序.OpenForms[fName];
如果(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=新点(this.x,this.y);
打破
}
}
这个.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();
}
私有无效计时器1_刻度(对象发送方,事件参数e)
{
开关(此操作)
{
case enmAction.wait:
计时器1.间隔=5000;
动作=enmAction.close;
打破
案例通知_form.enmAction.start:
this.timer1.Interval=1;
这是不透明度+=0.1;
if(this.x
对于那些会遇到相同问题的人,正如Jimi所说,本例中的主要问题是UI和FileSystemWatcher在不同的线程上工作,所以当我试图从MyFileWatcher调用表单时,它没有显示表单,因为调用来自不同的线程,我如何修复它?我在表单中设置了FileSystemWatcher的SynchronizingObject(所有学分归Jimi),如下:
fw.\u FileSystemWatcher.SynchronizingObject=this
其中
fw
是FileSystemWatcher对象,在从程序类创建时传递给form(注意:在这种情况下,传递给form以形成用于获取通知的相同对象很重要)

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


希望这有助于某人,有一天…

对于那些遇到同样问题的人,如