How to wait until File.Exists?
Solution 1
Actually FileSystemWatcher Created event called in separate thread by .NET itself.. So basically you need to do absolutely nothing. Your code is OK as it is.
Here is the proof:
class Program
{
static void Main(string[] args)
{
FileSystemWatcher fw = new FileSystemWatcher(@"C:\temp");
fw.Created += fileSystemWatcher_Created;
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
fw.EnableRaisingEvents = true;
Console.ReadLine();
}
static void fileSystemWatcher_Created(object sender, FileSystemEventArgs e)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
}
Solution 2
You can use sleep without locking the UI thread, you essentially sleep a seperate thread.
public event EventHandler FileCreated;
public void CheckFileExists()
{
while(!File.Exists(""))
{
Thread.Sleep(1000);
}
FileCreated(this, new EventArgs());
}
Then call this as:
Thread t = new Thread(CheckFileExists);
this.FileCreated += new EventHandler(somemethod);
t.Start();
public void SomeMethod(object sender, EventArgs e)
{
MessageBox.Show("File Created!");
}
Or as mentioned in another post use a BackGroundWorker
in place of the seperate thread, put the code I mentioned into DoWork
and listen for OnFinish
event but seeing as there isn't that much work to do either methods are fine.
Solution 3
You can use a BackGroundWorker to monitor the file system - and avoid freezing your UI
user1750355
Updated on July 12, 2020Comments
-
user1750355 almost 4 years
I have an app, listening for the *.log file in a chosen folder. I used
FileSystemWatcher
.But there is a problem. The other app responsible for making that file takes following steps:
- Make a *.gz file
- Unpack it to txt file (some random file name)
- Change the *.txt name to proper one with *.log extension.
And I can not change this behaviour.
So I made 2
FileSystemWatcher
s for *.gz, and *.txt files. Why? Because this app sometimes doesn't unpack the gz file, and sometimes doesn't rename the txt file to the final *.log file.FileSystemWatcher2
catches txt file, then (in the most cases it is renamed to log in the next 1000ms) I need to wait some time to check if txt file exists (if not, it seems to be renamed to the final *.log file).The question is, how to check if file exists without
Thread.Sleep()
to prevent UI freeze?I hope it is clear, if not I will try to describe it better. I think this is a complex problem.
Some code sample:
Watcher for gz file:
private void fileSystemWatcher_Created(object sender, FileSystemEventArgs e) { //this is for gz files in case if gz file is not unpacked automatically by other app //I need to wait and check if gz was unpacked, if not, unpack it by myself, //then txt watcher will catch that Thread.Sleep(5000); if (File.Exists(e.FullPath)) { try { byte[] dataBuffer = new byte[4096]; using (System.IO.Stream fs = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read)) { using (GZipInputStream gzipStream = new GZipInputStream(fs)) { string fnOut = Path.Combine(path_to_watcher, Path.GetFileNameWithoutExtension(e.FullPath)); using (FileStream fsOut = File.Create(fnOut)) { StreamUtils.Copy(gzipStream, fsOut, dataBuffer); } } } } catch { //Ignore } } }
Watcher for txt file:
private void fileSystemWatcher2_Created(object sender, FileSystemEventArgs e) { //this is for txt file Thread.Sleep(3500); if (File.Exists(e.FullPath)) { //make my actions } else { //make my actions } }
-
CodingGorilla over 11 yearsThis is probably better handled by either a
Task
orThreadPool.QueueUserWorkItem
. -
LukeHennerley over 11 years@CodingGorilla Obviously this would be dependant on the OP framework for task, but yeah your probably right :P