ASP.net Response.Redirect对FileSystemWatcher事件的影响

时间:2010-09-09 08:09:22

标签: asp.net filesystemwatcher

我无法在新的FileSystemWatcher事件上使用Response.Redirect(或Response.Write)。

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

    }

3 个答案:

答案 0 :(得分:4)

你想要的是不可能的。 FileSystemWatcher事件由与页面线程不同的线程处理。为了说明这一点:

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

Page_Load内的某个地方FileSystemWatcher已启动。页面生命周期以Page_UnLoad结束,并且运行页面生命周期的线程将返回到线程池。更重要的是,页面被渲染并完成,任何东西都不能再被更改。

在稍后的某个时刻,也许是一秒钟,也许十分钟,FileSystemWatcher会产生一个事件。页面已经很久以前由浏览器呈现,所以当你打电话给Response.Redirect时你会怎么想?由于响应已经发送到浏览器,因此不会发生任何事情。

此外,这最终会造成内存问题。每次请求此页面时,都会创建一个新的FileSystemWatcher。观察者必须维护对页面的引用,因为它必须在事件发生时调用事件处理程序。因此,页面和观察者都不能被垃圾收集。因此,每次请求此页面时,都会实例化页面和占用少量内存的观察程序,而这些内存永远不会被回收。

答案 1 :(得分:1)

正如其他人所说,你想做的事情是不可能的。但是,您可以通过以下方式创建类似的效果:

  1. 在Global.asax的Application_Start事件中创建一个新的FileSystemWatcher。
  2. 对于FileSystemWatcher OnChange事件,让它更新一个Cache变量(即Cache [“UploadedImagesChanged”],其中包含一个包含所需信息的对象(即LastChangeDateTime)。
  3. 在您的ASPX页面上,添加一个隐藏值以保存页面内数据的时间戳(即HiddenField_LastUpdated.Value = DateTime.Now.ToString())。
  4. 在Page_Load中,将当前的HiddenField_LastUpdated与Cache [“UploadedImagesChanged”] LastChangeDateTime进行比较。如果缓存日期较新,则Response.Redirect用户。
  5. 如果您希望页面轮询服务器以检查更新,您还可以考虑向页面添加asp:Timer和一些更新面板。

答案 2 :(得分:0)

我担心这不会起作用 - 你的文件夹观察者事件不是页面生命周期的一部分 - 你通常会有一些其他的线程或任务来运行来处理FSW,然后在某个地方保持你的状态。然后你可以说

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

希望有所帮助