FileSystemWatcher does not seem to be working

N

Nathan Sokalski

I have a directory on my site that I keep a bunch of text files in (this
directory is "/poetry/poems/"). The Application keeps the first line of each
of these files in an HttpApplicationState variable as a SortedList. When I
add or modify a file in this directory, I want to delete this
HttpApplicationState variable. I tried to do this using the following lines
of code in Global.asax.vb:


Private WithEvents poemfilewatcher As New
IO.FileSystemWatcher(HttpContext.Current.Server.MapPath("/poetry/poems/"))

Private Sub PoemDirModified(ByVal sender As Object, ByVal e As
System.IO.FileSystemEventArgs) Handles poemfilewatcher.Changed,
poemfilewatcher.Created, poemfilewatcher.Deleted
HttpContext.Current.Application.Lock()
HttpContext.Current.Application.Remove("poemlist")
HttpContext.Current.Application.UnLock()
End Sub

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
poemfilewatcher.IncludeSubdirectories = True
poemfilewatcher.EnableRaisingEvents = True
End Sub


The Function that I use to return this SortedList, whether it is stored in
an HttpApplicationState variable or not, is the following, which is also
located in Global.asax.vb:


Public Shared Function GetPoems() As SortedList 'Key=Title, Value=File
If HttpContext.Current.Application("poemlist") Is Nothing Then
Dim Poems As New SortedList(New CaseInsensitiveComparer)
Dim poemfiles As String() =
System.IO.Directory.GetFiles(HttpContext.Current.Server.MapPath("/poetry/poems/"))
Dim poemstreamreader As System.IO.StreamReader
Poems.Capacity = 50 'Not quite 50 poems, so call Poems.TrimToSize()
before caching
For Each poemfile As String In poemfiles
poemstreamreader = System.IO.File.OpenText(poemfile)
Poems.Add(poemstreamreader.ReadLine(), poemfile)
poemstreamreader.Close()
Next
Poems.TrimToSize()
HttpContext.Current.Application.Lock()
HttpContext.Current.Application.Add("poemlist", Poems)
HttpContext.Current.Application.UnLock()
Return Poems
Else
Return CType(HttpContext.Current.Application("poemlist"),
SortedList)
End If
End Function


However, when I add, delete, or modify a file in the directory it does not
seem to delete the HttpApplicationState variable. Am I forgetting to do
something? Am I doing something wrong? Any help would be appreciated, or
possibly an example that mentions all the necessary & required steps. Thank
you to anyone who can give me any help with this.
 
P

Peter Johnson

Nathan,

One thing I have learned from using the file system watcher previously
is that sometimes it's events trigger so soon after the file is created
/ modified that any code that references the file could be blocked as
the application that caused the creation / modification event still has
the file locked.

Try putting in a wait command for a few seconds to allow all locks on
the file to be cleared. Also I would specify a filter on the file
system watcher so that any files you don't want in there aren't picked
up.

The other thing is that from looking at your code it is possible the
file watcher could be going out of scope. Try looking at running the
file system watcher in a separate thread which is triggered by the
application start event, and ended by the application end event.

There is another way to implement this type of functionality which
would be to use the configuration sections of the web config, whenever
you add a file to the folder simply add it's first line of text and
filename to your sorted list. ASP.Net does automatically cycle when
the web config has been changed, this will ensure your list is always
updated accordingly, although it does add an extra degree of complexity
/ maintenance.
 
B

bruce barker \(sqlwork.com\)

you have a couple issues.

1) you need to dedicate a thread to the filewatcher. currently you are using
the first request thread. if no request come for a couple a seconds. request
threads come from a pool. if not reused, the thread is killed.

2) you are using HttpContext.Current. this will not be valid unless the the
event is fired while processing a request.

you should start a background thread, pass it a reference to the context,
and process the event.

-- bruce (sqlwork.com)
 
N

Nathan Sokalski

Those all sound like good, working solutions. I think that the two that I
would probably use one of is either the one about the wait command or the
one about creating a separate thread. However, both of those involve code
that I do not have experience using. The one for the wait command sounds
like it is pretty simple, I just need to see the code to use for it. I have
some experience with threads and what they are, just not in VB.NET, so if
you could show me a basic example of how to use a thread in VB.NET or direct
me to a site with some good examples, I would appreciate it. Thank you SO
MUCH for your help and quick response to this problem. Thanks.
 
P

Peter Johnson

Nathan,

The wait command should be used in tandem with creating a separate
thread. As it would happen to any thread the event is triggered upon.
Hard to believe but microsoft wrote the file system watcher and it is
Uber Efficient!!

Bruce has hit the nail on the head with creating a new thread so that
the file system watcher remains in scope regardless of the context of
the application. I'm unsure on how to implement the threading within
the web application, i've only done threading in windows services.
 
N

Nathan Sokalski

The responses that you and Peter have given me both seem like very good
advice, but like I have said, I don't really have any experience using
threads in VB.NET. This fact combined with what you have said about the
event needing to be fired while processing a request when used with ASP.NET
is making it kind of hard for me to figure out what to do about figuring out
a solution. Do you have any suggestions/ideas/recommended sites that could
help? Thanks.
 
B

Bob Lehmann

The responses that you and Peter have given me
If you wouldn't post to so many irrelevant groups, someone might have a clue
as to what Peter's response was.

microsoft.public.dotnet.framework.adonet,
microsoft.public.dotnet.framework.aspnet,
microsoft.public.dotnet.framework.aspnet.buildingcontrols,
microsoft.public.dotnet.framework.aspnet.webcontrols,
microsoft.public.dotnet.general,
microsoft.public.dotnet.l -> Apparently, you've reached some sort of limit
here

Bob Lehmann
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,735
Latest member
HikmatRamazanov

Latest Threads

Top