FileSystemWatcher at 99% cpu

  • Thread starter Thread starter Frank
  • Start date Start date
F

Frank

Hi,

I am using FileSystemWatcher to track the change in a text file. Whenever I
run the program I get 99% CPU utilization. The code doesn't do anything just
sits and waits in a while loop until the event is fired. Any ideas? Thanks

Frank
 
Frank said:
I am using FileSystemWatcher to track the change in a text file. Whenever I
run the program I get 99% CPU utilization. The code doesn't do anything just
sits and waits in a while loop until the event is fired. Any ideas? Thanks

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
Frank,

That's probably part of the problem. Why are you sitting in a while
loop? Are you doing anything else in the loop?
 
I figured it out. It seemes that the while loop is the fault. I changed the
while(true) to use Console.ReadLine() which helped.

using System.IO;

namespace ConsoleApplication1

{

/// <summary>

/// Summary description for Class1.

/// </summary>

class Class1

{

/// <summary>

/// The main entry point for the application.

/// </summary>

static bool bNew = false;

static void Main(string[] args)

{

FileSystemWatcher buildWatcher = new FileSystemWatcher();

buildWatcher.Path = "C:\\";

buildWatcher.NotifyFilter = NotifyFilters.LastWrite

| NotifyFilters.FileName;

buildWatcher.Filter = "myfile.txt";

buildWatcher.Changed += new FileSystemEventHandler(OnChanged);

while (true)

{

if (bNew)

{

//. something to do here

}

}

}

public static void OnChanged(object source, FileSystemEventArgs e)

{

bNew = true;

}

}

}
 
Frank said:
I figured it out. It seemes that the while loop is the fault. I changed the
while(true) to use Console.ReadLine() which helped.

Yes - the while(true) is certainly where the trouble is. You should
never, ever put a tight loop in your code like this - it will always
give this kind of result.

Now, why don't you want to do the work directly when the event handler
is called?
 
Just as an FYI, here's my code for something similar:

private void btnStartMonitoring_Click(object sender, EventArgs e)
{
System.IO.FileSystemWatcher fsw = new
FileSystemWatcher(txtDirectoryName.Text.ToString());
fsw.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite |
NotifyFilters.FileName | NotifyFilters.DirectoryName;
fsw.Filter = "*.cnk";
fsw.Created += new FileSystemEventHandler(OnCreated);
// Begin watching.
fsw.EnableRaisingEvents = true;
}

private static void OnCreated(object source, FileSystemEventArgs e)
{
string sMessage = "File: " + e.FullPath + " " + e.ChangeType;
MessageBox.Show(sMessage);
}

There is no loop monitoring the status; it simply fires when the event
occurs. Now one thing I'm still fighting with is that I need to Invoke the
process to happen afterwards, otherwise the UI does goofy things. See my
post from 04/08/06. But that's just tweaking... :) Famous last words.

Clint


Frank said:
I figured it out. It seemes that the while loop is the fault. I changed the
while(true) to use Console.ReadLine() which helped.

using System.IO;

namespace ConsoleApplication1

{

/// <summary>

/// Summary description for Class1.

/// </summary>

class Class1

{

/// <summary>

/// The main entry point for the application.

/// </summary>

static bool bNew = false;

static void Main(string[] args)

{

FileSystemWatcher buildWatcher = new FileSystemWatcher();

buildWatcher.Path = "C:\\";

buildWatcher.NotifyFilter = NotifyFilters.LastWrite

| NotifyFilters.FileName;

buildWatcher.Filter = "myfile.txt";

buildWatcher.Changed += new FileSystemEventHandler(OnChanged);

while (true)

{

if (bNew)

{

//. something to do here

}

}

}

public static void OnChanged(object source, FileSystemEventArgs e)

{

bNew = true;

}

}

}
 
I am using console application, so I need to stay in some kind of a loop for
the program not to exit. I probably could move the work load into the event
handler but checking errors to determine when to exit the program. The
reason that I didn't use the Console class is that it sits there waiting for
input from the user when the program really is autonomous running in the
background.

Frank
 
Frank said:
I am using console application, so I need to stay in some kind of a loop for
the program not to exit. I probably could move the work load into the event
handler but checking errors to determine when to exit the program. The
reason that I didn't use the Console class is that it sits there waiting for
input from the user when the program really is autonomous running in the
background.

Okay, a few things:

1) You probably don't actually need it to be a console app. Unless
you're *using* the console, it would probably look better as a WinForms
app which just doesn't bring up any forms - that way you wouldn't have
a blank window up for no reason.

2) If you need to capture multiple events, you could use a
producer/consumer queue, where the file system event "produces" an item
which is then consumed by the main loop.

3) If you only need to capture a single event, you can just use
Monitor.Wait/Pulse.

See http://www.pobox.com/~skeet/csharp/threads/deadlocks.shtml for more
information on these (from half way down).
 
Back
Top