C# Loop 方法每分钟,它的文件存在做一些事情,如果不等到它被创建
C# Loop method every minute, it file exist do something, if not wait untill its created
我有一个程序可以检查是否创建了 .csv 文件。如果创建了,就做一些事情,如果没有等到它创建。在 C# 中可以吗?
尝试过类似的方法但效果不佳...
var startTimeSpan = TimeSpan.Zero;
var periodTimeSpan = TimeSpan.FromMinutes(1);
var timer = new System.Threading.Timer((e) =>
{
if (!File.Exists(@"TestFileLocation"))
{
MethodName(); //Tried this to start method agian
}
else
{
HereIsRestOfTheCodeToDoSomeActions();
}
}, null, startTimeSpan, periodTimeSpan);
如果我的 post 不够清楚,抱歉我英语不流利,下面是步骤,程序将如何运行:
- 检查文件夹中是否创建了文件
- 如果没有,等1分钟再检查
- 如果文件被创建做一些事情
- 从头开始循环此步骤
创建 FileSystemWatcher https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=net-6.0 并在 OnCreated
中添加检查
最适合您的问题的方法是使用 FileSystemWatcher。它的工作是监视目录的变化,例如在您的问题中需要它时创建文件。
这也会使 one-minute-threshold 过时。考虑例如:
// necessary assembly using for using FileSystemWatcher classes.
using System.IO;
// ...
// instantiate your watcher.
using var watcher = new FileSystemWatcher(@"C:\path\to\folder");
// just filter for interesting attribtes.
watcher.NotifyFilter = NotifyFilters.FileName;
// attach an event handler to the event that is triggered when a file is created.
watcher.Created += OnCreated;
// ...
// implement the event handler.
private static void OnCreated(object sender, FileSystemEventArgs e)
{
// if the name is "your" name, you're ready to go ...
if (e.Name == "my_name")
// do something ...
}
但是,如果您仍想使用循环(由于您未在 post 中说明的限制),那么它可能类似于以下 less adorable 方法:
var now = DateTime.Now;
var waitTime = TimeSpan.FromMinutes(1);
while (true)
{
if (!File.Exists(@"TestFileLocation"))
{
// do something ...
// exit the loop.
break;
}
Thread.Sleep(waitTime);
}
注意并注意这个endless-loop会阻塞主线程,直到您找到您的文件。更好的方法是在主线程之外的单独线程中执行该任务。
除了将代码包装到 class 之外,此代码与 @markwellman 相同。代码不会等待,它会持续监控并且看不出停止和启动的原因。
在下面的示例中,在 FileOperations
的构造函数中传递要监视的文件夹和要监视的文件文件名
using System;
using System.IO;
using static System.IO.Path;
namespace YourNamespace
{
public class FileOperations : FileSystemWatcher
{
/// <summary>
/// Path to check for file
/// </summary>
public string MonitorPath { get; set; }
/// <summary>
/// File name to watch for
/// </summary>
public string FileName { get; set; }
public FileOperations(string monitorPath, string fileName)
{
if (!Directory.Exists(monitorPath))
{
throw new Exception($"Missing {monitorPath}");
}
MonitorPath = monitorPath;
Created += OnCreated;
Path = MonitorPath;
Filter = fileName;
FileName = fileName;
EnableRaisingEvents = true;
NotifyFilter = NotifyFilters.FileName;
}
private void OnCreated(object sender, FileSystemEventArgs e)
{
var fileName = Combine(MonitorPath, GetFileName(e.FullPath));
if (fileName.Equals(Combine(MonitorPath,FileName), StringComparison.OrdinalIgnoreCase))
{
// TODO
}
}
public void Start()
{
EnableRaisingEvents = true;
}
public void Stop()
{
EnableRaisingEvents = false;
}
}
}
然后在表单中创建 FileOperations
的私有实例。在窗体关闭事件中调用 Stop 方法。
public partial class Form1 : Form
{
private readonly FileOperations _fileOperations =
new FileOperations("Path to watch", "file name to trigger on");
public Form1()
{
InitializeComponent();
Closing += OnClosing;
}
private void OnClosing(object sender, CancelEventArgs e)
{
_fileOperations.Stop();
}
}
我有一个程序可以检查是否创建了 .csv 文件。如果创建了,就做一些事情,如果没有等到它创建。在 C# 中可以吗?
尝试过类似的方法但效果不佳...
var startTimeSpan = TimeSpan.Zero;
var periodTimeSpan = TimeSpan.FromMinutes(1);
var timer = new System.Threading.Timer((e) =>
{
if (!File.Exists(@"TestFileLocation"))
{
MethodName(); //Tried this to start method agian
}
else
{
HereIsRestOfTheCodeToDoSomeActions();
}
}, null, startTimeSpan, periodTimeSpan);
如果我的 post 不够清楚,抱歉我英语不流利,下面是步骤,程序将如何运行:
- 检查文件夹中是否创建了文件
- 如果没有,等1分钟再检查
- 如果文件被创建做一些事情
- 从头开始循环此步骤
创建 FileSystemWatcher https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=net-6.0 并在 OnCreated
中添加检查最适合您的问题的方法是使用 FileSystemWatcher。它的工作是监视目录的变化,例如在您的问题中需要它时创建文件。
这也会使 one-minute-threshold 过时。考虑例如:
// necessary assembly using for using FileSystemWatcher classes.
using System.IO;
// ...
// instantiate your watcher.
using var watcher = new FileSystemWatcher(@"C:\path\to\folder");
// just filter for interesting attribtes.
watcher.NotifyFilter = NotifyFilters.FileName;
// attach an event handler to the event that is triggered when a file is created.
watcher.Created += OnCreated;
// ...
// implement the event handler.
private static void OnCreated(object sender, FileSystemEventArgs e)
{
// if the name is "your" name, you're ready to go ...
if (e.Name == "my_name")
// do something ...
}
但是,如果您仍想使用循环(由于您未在 post 中说明的限制),那么它可能类似于以下 less adorable 方法:
var now = DateTime.Now;
var waitTime = TimeSpan.FromMinutes(1);
while (true)
{
if (!File.Exists(@"TestFileLocation"))
{
// do something ...
// exit the loop.
break;
}
Thread.Sleep(waitTime);
}
注意并注意这个endless-loop会阻塞主线程,直到您找到您的文件。更好的方法是在主线程之外的单独线程中执行该任务。
除了将代码包装到 class 之外,此代码与 @markwellman 相同。代码不会等待,它会持续监控并且看不出停止和启动的原因。
在下面的示例中,在 FileOperations
using System;
using System.IO;
using static System.IO.Path;
namespace YourNamespace
{
public class FileOperations : FileSystemWatcher
{
/// <summary>
/// Path to check for file
/// </summary>
public string MonitorPath { get; set; }
/// <summary>
/// File name to watch for
/// </summary>
public string FileName { get; set; }
public FileOperations(string monitorPath, string fileName)
{
if (!Directory.Exists(monitorPath))
{
throw new Exception($"Missing {monitorPath}");
}
MonitorPath = monitorPath;
Created += OnCreated;
Path = MonitorPath;
Filter = fileName;
FileName = fileName;
EnableRaisingEvents = true;
NotifyFilter = NotifyFilters.FileName;
}
private void OnCreated(object sender, FileSystemEventArgs e)
{
var fileName = Combine(MonitorPath, GetFileName(e.FullPath));
if (fileName.Equals(Combine(MonitorPath,FileName), StringComparison.OrdinalIgnoreCase))
{
// TODO
}
}
public void Start()
{
EnableRaisingEvents = true;
}
public void Stop()
{
EnableRaisingEvents = false;
}
}
}
然后在表单中创建 FileOperations
的私有实例。在窗体关闭事件中调用 Stop 方法。
public partial class Form1 : Form
{
private readonly FileOperations _fileOperations =
new FileOperations("Path to watch", "file name to trigger on");
public Form1()
{
InitializeComponent();
Closing += OnClosing;
}
private void OnClosing(object sender, CancelEventArgs e)
{
_fileOperations.Stop();
}
}