I have a FileSystemWatcher which monitors a directory for text files and when found it shows part of text in the textbox. I tried adding a breakpoint and saw that the .Text
property have the desired value but I’m not able to see it on the client side(webform).
asp
<asp:TextBox ID="txtName" runat="server" EnableViewState="true"></asp:TextBox>
C#
FileSystemWatcher watcher;
protected void Page_Load(object sender, EventArgs e)
{
watcher = new FileSystemWatcher(path);
watcher.Created += OnFileCreated;
watcher.Changed += OnFileCreated;
watcher.InternalBufferSize = 64000;
watcher.Filter = "*.txt";
watcher.EnableRaisingEvents = true;
}
private void OnFileCreated(object sender, FileSystemEventArgs e)
{
if(e.Name == fileName)
{
try
{
if(File.Exists(fileName))
{
string[] lines = File.ReadAllLines(fileName);
if (lines.Length >= 3)
{
if (lines[1] == string.Empty || lines[1] == null)
{
string message = "Not a valid value";
ClientScript.RegisterStartupScript(this.GetType(), "alert", "alert('" + message + "');", true);
}
else
{
string name = lines[1];
txtname.Text = name;
}
}
else
{
Console.WriteLine("The file does not have at least 3 lines.");
}
}
}
catch (Exception ex)
{
errorTxt.Text = ex.ToString();
}
}
}
When breakpoint is added I can see that txtname.Text = name;
have name
value
2
Answers
The problem will be that your code setting the textbox.text property is running server-side, so if the page displaying the textbox was refreshed then it would display the text you are expecting. If you want the textbox to update without a page refresh then you’ll need some client-side code to handle it, but alternatively you could just the page every so often by including a meta refresh line in your page header, e.g.
This design can’t work.
Code that subscribes to folder events MUST be running and available code.
However, the new concept when writing web-based software is of course the concept that web-based software is state less. That means that once a web page is rendered, and sent to the client side (user’s browser), then on server side the code, the memory, the variables are all destroyed, removed from memory and they DO NOT exist anymore!
Thus the code and variables are now out of scope.
This is much like calling a sub routine. When code completes, then all of the code, the local variables of that subroutine you called are now gone and out of scope.
So, when you hit a button, or trigger a post back?
Then we have the start of the so-called round trip.
This web so called round-trip is much like calling a subroutine – when all is done, then all scope is lost for that code.
We thus have this:
Note how your page class and code behind?
It DOES NOT yet exist in memory!!!!
NOTE VERY careful here – the web page is ON THE CLIENT computer – it is NOT existing at all on the web server side.
So, we not have this:
So, while the browser is sitting on the user’s desktop there is NOT A copy of the code behind to call, or be called by subscribing that code to the file watcher event handler.
You can’t run (call) such code since there is no copy in memory to run or call. And worse, WHILE people are dropping file(s) into that folder, there will NOT be a copy of the code in memory to call, and thus such code can’t update the browser. Worse yet, is once you miss such events, then you can’t get them back – they are lost forever. Now, the existence of a file having been copied into that folder is also lost forever.
So, with above, then you might say click a button on the web page.
This is the start of the so-called round trip, and without a grasp of this concept then you can’t actually write web-based software!!!
So, when you click on a button, or do a post-back, then you get this:
Our web page is sent up to the server. You now have this:
(but our code behind IS NOT YET RUNNING OR existing!!!!).
NOW an instance of the page class is created, and your code behind starts running.
Your code behind can modify controls (even controls to be visible or not), but the page is NOT interacting with the user – ONLY code can MODIFY the web page. So, one change, or MANY changes to the web page can occur, but AS YOU update things like a text box etc., the user does NOT see these changes just yet. So, you can’t say run a loop to flash a text box on and off – since the changes are occurring on the server – the client-side browser does not have the web page anymore!!!
When ALL of the code is done running, then the web page is sent back to the client side, and they will now see updates to the web page.
The server-side class instance and code are TOSSED OUT – DOES NOT exist!!! Your server-side page class is disposed – removed from memory, and the web page code behind does NOT exist anymore.
So, ONLY during this very small time frame could subscribed events to the file watcher work, or update the web page.
Once server code has completed, then the web page travels back to the client side, is re-displayed, JavaScript is loaded, and THEN JavaScript starts running.
So, the issue here is that once the web page is sent to client side, then the server-side code and variables are ALL DESTROYED.
That means now the code that subscribed to the file watcher events will not work. As users drop file(s) into that folder, then no instance of that code exists to be called. And even if the code WAS to be called, then web browser page is sitting on the user’s desktop, and the server-side code can’t reach out and modify that browser.
This quite much suggests that you have to dump the file watcher code, and simply each time you refresh, then get some kind of last date, or file count, and compare. As noted, you dealing with two issues, and one looming issue is that in web land, once the web page is sent client side, then the server-side code is gone, disposed, and out of scope. (thus, during that time, new file events can’t be processed, and will be missed).
But MUCH worse is that file watcher events DO NOT remember between the last time you run such code!!! In other words, if for ANY reason the file watcher code can’t run, then you MISSED the fact of a file copy/change in that folder. If you stop such code, and run say tomorrow, then such code will NOT show the files that were copied in the past, but ONLY during live running of that code do such events fire.
Given the state-less nature of web software, then adopting file watcher code is even more of a challenge, since with a state less system, then we have to assume that often such code will not be in memory and running.
In fact, for desktop or console applications, in EVERY case in the past, we had to drop use of file watcher code, since if that process stopped running, then how do we get it started again, since all the files copied into the folder when the software was not working is now lost! What we wind up doing is writing some code to check for new files, but if we are having to write such code, then we might as well drop the file watcher event code model then, right?
However, while the above is difficult, that’s console or desktop software. With web land? Forget this idea, it is an non starter design.
Now, you COULD adopt a real time setup, and to do this would require you to adopt signalR, and live always on web-socket from the client side to the browser side. This can be done, and for real-time software, or even say a chat board that allows you to see typing in real time, then such a software stack can be adopted.
However, the current setup you have simply cannot be used, due to the scope issue, but worse due to that code NOT running all the time will all too often miss file events.
So, SignalR is a possible option here, and you can read about signalR here:
https://learn.microsoft.com/en-us/aspnet/signalr/
Often, in most cases, a simple loop and writing your own pooling works better, since you can re-start the software, and missed file events thus don’t matter.