如何观看和等待文件创建? [英] How can I watch and wait until file is created?

查看:87
本文介绍了如何观看和等待文件创建?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用FileSystemWatcher。
我是通过按钮单击事件调用WatchDirectory的。
然后,我想在文件忙于显示忙时分配给label6.Text,而在文件不忙时再显示不忙。

I'm using FileSystemWatcher. I'm calling the WatchDirectory from a button click event. Then i want assign to label6.Text once the file is busy to display "busy" and when the file is not busy any more to display "not busy".

使用异步我不确定这里是否正确。
这种等待方法是我遇到错误。

And using async i'm not sure if it's the right way here. This wait the methods are i'm getting errors.

在WatchDirectory上我遇到了错误:

On WatchDirectory i'm getting the error:

找不到'async'修饰符所需的所有类型。您是针对错误的框架版本,还是缺少对程序集的引用?

Cannot find all types required by the 'async' modifier. Are you targeting the wrong framework version, or missing a reference to an assembly?

在线上出现相同错误:return await tcs.Task;

Same error on the line: return await tcs.Task;

在WaitForUnlockedFile上我遇到了错误:

On WaitForUnlockedFile i'm getting the error:

找不到'async'修饰符所需的所有类型。您是针对错误的框架版本,还是缺少对程序集的引用?

Cannot find all types required by the 'async' modifier. Are you targeting the wrong framework version, or missing a reference to an assembly?

最后一个错误:

await Task.Delay(100);

'System.Threading.Tasks.Task'不包含'Delay'的定义

'System.Threading.Tasks.Task' does not contain a definition for 'Delay'

private async Task<string> WatchDirectory()
        {
            using (FileSystemWatcher watcher = new FileSystemWatcher())
            {
                TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();

                watcher.Path = SavePathTextBox.Text;
                watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size;
                watcher.Filter = "*.jpg";
                watcher.Changed += (sender, e) =>
                {
                    if (e.ChangeType == WatcherChangeTypes.Changed)
                    {
                        var info = new FileInfo(e.FullPath);
                        var theSize = info.Length;
                        label5.BeginInvoke((Action)(() =>
                        {
                            label6.Text = theSize.ToString();
                        }));
                    }
                    tcs.SetResult(e.FullPath);
                };
                watcher.EnableRaisingEvents = true;

                return await tcs.Task;
            }
        }

和WaitForUnlockedFile方法

And the WaitForUnlockedFile method

private async Task WaitForUnlockedFile(string fileName)
    {
        while (true)
        {
            try
            {
                using (IDisposable stream = File.Open(fileName, FileMode.OpenOrCreate,
                    FileAccess.ReadWrite, FileShare.None))
                { /* on success, immediately dispose object */ }

                break;
            }
            catch (IOException)
            {
            }
            await Task.Delay(100);
        }
    }


推荐答案

所以第一个关键点是,当文件系统事件在特定路径上更改时,可以使用FileSystemWatcher来通知。例如,如果希望在特定位置创建文件时收到通知,则可以查找。

So the first key point is that you can use a FileSystemWatcher to be notified when a file system event changes at a particular path. If you, for example, want to be notified when a file is created at a particular location you can find out.

下一步,我们可以创建一个使用TaskCompletionSource的方法在文件系统监视程序触发相关事件时触发任务完成。

Next, we can create a method that uses a TaskCompletionSource to trigger the completion of a task when the file system watcher triggers the relevant event.

public static Task WhenFileCreated(string path)
{
    if (File.Exists(path))
        return Task.FromResult(true);

    var tcs = new TaskCompletionSource<bool>();
    FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(path));

    FileSystemEventHandler createdHandler = null;
    RenamedEventHandler renamedHandler = null;
    createdHandler = (s, e) =>
    {
        if (e.Name == Path.GetFileName(path))
        {
            tcs.TrySetResult(true);
            watcher.Created -= createdHandler;
            watcher.Dispose();
        }
    };

    renamedHandler = (s, e) =>
    {
        if (e.Name == Path.GetFileName(path))
        {
            tcs.TrySetResult(true);
            watcher.Renamed -= renamedHandler;
            watcher.Dispose();
        }
    };

    watcher.Created += createdHandler;
    watcher.Renamed += renamedHandler;

    watcher.EnableRaisingEvents = true;

    return tcs.Task;
}

因此,第一个关键点是可以使用FileSystemWatcher在以下情况下收到通知文件系统事件在特定路径上发生更改。例如,如果希望在特定位置创建文件时收到通知,则可以查找。

So the first key point is that you can use a FileSystemWatcher to be notified when a file system event changes at a particular path. If you, for example, want to be notified when a file is created at a particular location you can find out.

下一步,我们可以创建一个使用TaskCompletionSource的方法在文件系统监视程序触发相关事件时触发任务完成。

Next, we can create a method that uses a TaskCompletionSource to trigger the completion of a task when the file system watcher triggers the relevant event.

public static Task WhenFileCreated(string path)
{
    if (File.Exists(path))
        return Task.FromResult(true);

    var tcs = new TaskCompletionSource<bool>();
    FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(path));

    FileSystemEventHandler createdHandler = null;
    RenamedEventHandler renamedHandler = null;
    createdHandler = (s, e) =>
    {
        if (e.Name == Path.GetFileName(path))
        {
            tcs.TrySetResult(true);
            watcher.Created -= createdHandler;
            watcher.Dispose();
        }
    };

    renamedHandler = (s, e) =>
    {
        if (e.Name == Path.GetFileName(path))
        {
            tcs.TrySetResult(true);
            watcher.Renamed -= renamedHandler;
            watcher.Dispose();
        }
    };

    watcher.Created += createdHandler;
    watcher.Renamed += renamedHandler;

    watcher.EnableRaisingEvents = true;

    return tcs.Task;
}

请注意,这首先检查文件是否存在,以允许其正确退出如果适用,请离开。它还使用创建的处理程序和重命名的处理程序,因为这两个选项都可能允许文件在将来的某个时刻存在。 FileSystemWatcher也只监视目录,因此获取指定路径的目录,然后在事件处理程序中检查每个受影响文件的文件名很重要。

Note that this first checks if the file exists, to allow it to exit right away if applicable. It also uses both the created and renamed handlers as either option could allow the file to exist at some point in the future. The FileSystemWatcher also only watches directories, so it's important to get the directory of the specified path and then check the filename of each affected file in the event handler.

还请注意,

这允许我们编写:

public static async Task Foo()
{
    await WhenFileCreated(@"C:\Temp\test.txt");
    Console.WriteLine("It's aliiiiiive!!!");
}

异步等待文件创建

这篇关于如何观看和等待文件创建?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆