gpt4 book ai didi

c# - 在多线程上下文中使用超时监视文件锁释放

转载 作者:行者123 更新时间:2023-11-30 17:53:36 27 4
gpt4 key购买 nike

我正在使用 FileSystemWatcher 在文件到达我的系统文件夹时通知我。

有时,他们会带着锁(通过其他程序)到达

我想执行如下操作:

如果在 TIMEOUT 之后它们仍然被锁定,我们将忽略该文件或者如果它们在我们处理文件的 TIMEOUT 内变为自由锁

我目前想出了这个解决方案,但想知道是否有任何其他方法可以实现它。

 lockedFilePaths = new List<string>();
NoLockFilePaths = new List<string>();

Watcher.Created += (sender, e) => WatcherHandler(e.FullPath);

WatcherHandler(string FilePath)
{
CheckFileAccess(FilePath);
if (NoLockFilePaths.Any())
{
//Process all file paths
}
}

CheckFileAccess(string filepath)
{
// start a timer and invoke every say 10ms
// log the locked time of the file.
// compare the current time.
// return null if TIMEOUT exceeds
// or wait till the TIMEOUT and keep on checking the file access
}

问题是如何简单优化地实现CheckFileAccess?

我目前使用 System.Threading.Timer 每 1000 毫秒通知我一次,检查文件是否仍被锁定以及我的实现是否令我满意。寻找一些 super 简单实现的建议。

最佳答案

如果我必须做类似的事情,我会这样做:

public class Watcher
{
public readonly TimeSpan Timeout = TimeSpan.FromMinutes(10);

private readonly FileSystemWatcher m_SystemWatcher;
private readonly Queue<FileItem> m_Files;
private readonly Thread m_Thread;
private readonly object m_SyncObject = new object();
public Watcher()
{
m_Files = new Queue<FileItem>();
m_SystemWatcher = new FileSystemWatcher();
m_SystemWatcher.Created += (sender, e) => WatcherHandler(e.FullPath);
m_Thread = new Thread(ThreadProc)
{
IsBackground = true
};
m_Thread.Start();
}

private void WatcherHandler(string fullPath)
{
lock (m_SyncObject)
{
m_Files.Enqueue(new FileItem(fullPath));
}
}

private void ThreadProc()
{
while(true)//cancellation logic needed
{
FileItem item = null;
lock (m_SyncObject)
{
if (m_Files.Count > 0)
{
item = m_Files.Dequeue();
}
}

if (item != null)
{
CheckAccessAndProcess(item);
}
else
{
SpinWait.SpinUntil(() => m_Files.Count > 0, 200);
}
}
}

private void CheckAccessAndProcess(FileItem item)
{
if (CheckAccess(item))
{
Process(item);
}
else
{
if (DateTime.Now - item.FirstCheck < Timeout)
{
lock (m_SyncObject)
{
m_Files.Enqueue(item);
}
}
}
}

private bool CheckAccess(FileItem item)
{
if (IsFileLocked(item.Path))
{
if (item.FirstCheck == DateTime.MinValue)
{
item.SetFirstCheckDateTime(DateTime.Now);
}
return false;
}

return true;
}

private void Process(FileItem item)
{
//Do process stuff
}

private bool IsFileLocked(string file)
{
FileStream stream = null;
var fileInfo = new FileInfo(file);

try
{
stream = fileInfo.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
if (stream != null)
stream.Close();
}
return false;
}
}

public class FileItem
{
public FileItem(string path)
{
Path = path;
FirstCheck = DateTime.MinValue;
}

public string Path { get; private set; }
public DateTime FirstCheck { get; private set; }

public void SetFirstCheckDateTime(DateTime now)
{
FirstCheck = now;
}
}

从 CheckAccess 和 IsFileLocked 中,您可以返回 FileStream 对象,以确保不会从 CheckAccess 和 Process 调用之间的另一个进程获取文件句柄;

关于c# - 在多线程上下文中使用超时监视文件锁释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17161091/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com