Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 释放文件锁时收到通知_C#_.net_Filesystemwatcher_Ntfs_Filelock - Fatal编程技术网

C# 释放文件锁时收到通知

C# 释放文件锁时收到通知,c#,.net,filesystemwatcher,ntfs,filelock,C#,.net,Filesystemwatcher,Ntfs,Filelock,[使用C#和Windows作为平台] 我有一个摄像头,可以将JPG文件写入电脑中的本地文件夹。我想加载摄像头丢弃的每个文件,因此我有一个FileSystemWatcher,它可以在创建新图片时通知我,但摄像头会在写入文件时锁定该文件,因此如果我在收到创建通知后尝试加载该文件,我收到一个异常,文件被锁定 目前,我有一个while循环(带有Thread.Sleep),它每0.2秒重试一次加载映像,但感觉有点脏 是否有一种更优雅的方法来等待锁被释放,这样我就可以加载文件,确保不再使用它???您将无法绕

[使用C#和Windows作为平台]

我有一个摄像头,可以将JPG文件写入电脑中的本地文件夹。我想加载摄像头丢弃的每个文件,因此我有一个FileSystemWatcher,它可以在创建新图片时通知我,但摄像头会在写入文件时锁定该文件,因此如果我在收到创建通知后尝试加载该文件,我收到一个异常,文件被锁定

目前,我有一个while循环(带有Thread.Sleep),它每0.2秒重试一次加载映像,但感觉有点脏


是否有一种更优雅的方法来等待锁被释放,这样我就可以加载文件,确保不再使用它???

您将无法绕过反复尝试的方法,即尝试打开文件,捕获IOException,然后重试。但是,您可以将这种丑陋隐藏在单独的类中,如下所示:

public class CustomWatcher
{
    private readonly FileSystemWatcher watcher;
    public event EventHandler<FileSystemEventArgs> CreatedAndReleased;

    public CustomWatcher(string path)
    {
        watcher = new FileSystemWatcher(path, "*.jpg");
        watcher.Created += OnFileCreated;
        watcher.EnableRaisingEvents = true;
    }

    private void OnFileCreated(object sender, FileSystemEventArgs e)
    {
        // Running the loop on another thread. That means the event
        // callback will be on the new thread. This can be omitted
        // if it does not matter if you are blocking the current thread.
        Task.Run(() =>
        {
            // Obviously some sort of timeout could be useful here.
            // Test until you can open the file, then trigger the CreeatedAndReleased event.
            while (!CanOpen(e.FullPath))
            {
                Thread.Sleep(200);
            }
            OnCreatedAndReleased(e);
        });
    }

    private void OnCreatedAndReleased(FileSystemEventArgs e)
    {
        CreatedAndReleased?.Invoke(this, e);
    }

    private static bool CanOpen(string file)
    {
        FileStream stream = null;
        try
        {
            stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.None);
        }
        catch (IOException)
        {
            return false;
        }
        finally
        {
            stream?.Close();
        }
        return true;
    }
}

免责声明:CustomWatcher可能需要IDisposable并适当地处置FileSystemWatcher。代码仅显示了如何实现所需功能的示例。

我不想知道它是否已锁定。我希望在文件未被锁定时得到通知。请看一看,Puropoix引用的问题中的公认答案建议考虑一件好事:即使您知道该文件已被释放,在您打开它之前,它可能会再次被锁定。因此,可靠的方法是在收到锁释放通知后,尝试在循环中打开文件。这只是一个评论。
var watcher = new CustomWatcher("path");
watcher.CreatedAndReleased += (o,e) => 
{
    // Now, your watcher has managed to open and close the file,
    // so the camera is done with it. Obviously, any other application
    // is able to lock it before this code manages to open the file.
    var stream = File.OpenRead(e.FullPath);
}