views:

34

answers:

3

I don't manage to use a Response.Redirect (or Response.Write) on a new FileSystemWatcher event.

protected void Page_Load(object sender, EventArgs e)
{
   RunFolderListener();
}

private void RunFolderListener()
{
        FileSystemWatcher fsw = new FileSystemWatcher();
        fsw.Path = Server.MapPath("~/uploaded_images/");
        fsw.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite |
                           NotifyFilters.DirectoryName | NotifyFilters.FileName;
        fsw.Changed += new FileSystemEventHandler(OnChanged);
        fsw.EnableRaisingEvents = true;
}

    private void OnChanged(object source, FileSystemEventArgs e)
    {
        Response.Redirect(....); //not working
        Response.Write (....);//not working

    }
A: 

I'm afraid that's not going to work -- your folder watcher event isn't part of the page life cycle -- you would normally have some other thread or task to run to handle the FSW, then persist your state somewhere. Then you can say

protected void Page_Load(object sender, EventArgs e)
{
   if (myState.FileIngested) {
      Response.Redirect(....);
      Response.End();
   }
}

Hope that helps

Iain Ballard
+2  A: 

What you want is impossible. The FileSystemWatcher events are handled by a different thread than the page thread. To illustrate this:

Page thread: |-Page_Load----...----Page_Unload-|
                 |-Start FSW
FSW thread :     |-----------------------------...--------FSW.OnChanged(...)---|

Somewhere inside Page_Load the FileSystemWatcher is started. The page lifecycle ends with a Page_UnLoad and the thread that ran the page lifecycle is returned to the thread pool. And more importantly, the page is rendered and finished and nothing can be changed anymore.

At some later moment in time, maybe one second, maybe ten minutes, the FileSystemWatcher generates an event. The page has been rendered by the browser a long time ago, so what do you think should happen when you call Response.Redirect? Since the response was already sent to the browser, nothing will happen.

Besides, this will eventually create memory problems. Each time you request this page, a new FileSystemWatcher is created. The watcher has to maintain a reference to the page because it has to call the event handler when an event occurs. Both the page and the watcher can therefore not be garbage-collected. So each time you request this page, you instantiate the page and a watcher that occupy a small amount of memory that is never reclaimed.

Ronald Wildenberg
Actually I tried to create this mechanism (FSW) in order to catch a Flash event :user clicks on a Flash button on my page to upload a file.When the file is uploaded, an aspx page is called (the image is sent by form submit to this page). I could not use Redirect on that page, so I tried using the FSW instead.Since I cannot modify the Flash - I need another solution to change the page location on a Flash event.
Ranch
I'm not sure I understand why you can't use a redirect on the aspx page that you post the image to?
Ronald Wildenberg
The page the image is submitted to is not the page with the Flash object.
Ranch
If this is a synchronous form submit (not some Ajax submit), you should be able to do a redirect in the page you're posting to. It doesn't really matter where you are posting from.
Ronald Wildenberg
This is where I started from, but since the Redirect was not working on the page the image was submitted to I started looking for alternate solution (FSW...).Should I assume, because the Redirect is not working, that the Flash is using Ajax submit ? other solution for the redirect or can it be initiated only by the Flash object ?Since the Flash part was not written by me, I rather use asp.net solution than trying to modify it.
Ranch
I don't think the Flash object is causing an async file upload because that's pretty hard to do. Do you see the page reload when the file is uploaded? If you do, then it's not async. What I always do when I'm not sure what traffic is going on between browser and server, is to install Fiddler (http://www.fiddler2.com/fiddler2/) and check what's really going on.
Ronald Wildenberg
A: 

As the other's have mentioned, what you're looking to do is not possible. However, you can create a similar effect by:

  1. Create a new FileSystemWatcher within your Global.asax's Application_Start event.
  2. For the FileSystemWatcher OnChange event, have it update a Cache variable (ie Cache["UploadedImagesChanged"] with an object containing the info you need (ie LastChangeDateTime).
  3. On your ASPX page, add a hidden value to hold a timestamp for the data within the page (ie HiddenField_LastUpdated.Value=DateTime.Now.ToString()).
  4. Within your Page_Load, compare the current HiddenField_LastUpdated with the Cache["UploadedImagesChanged"] LastChangeDateTime. If the Cached date is newer, Response.Redirect the user.

You can also consider adding an asp:Timer to the page and some update panels if you want the page to poll the server to check for updates.

o6tech
The FileSystemWatcher will create an event only after PageLoad, since it is the page itself that initiates a file upload (using a Flash object within it. See my comment to Ronald Wildenberg),therefore the PageLoad will never catch this event.On the other hand using a asp:Timer (which I actually never encountered with) might be a solution (not the most elegant one - but I think it should work).
Ranch
I was trying using asp:Timer which might have been a solution. The problem is causes the Flash object to reload each tick which make it impossible to use.
Ranch
If you put surround the Timer in it's own UpdatePanel, it shouldn't affect the flash object on the page. Also, make sure that any other UpdatePanel on the page is set to update conditionally. Give that a shot.
o6tech