【问题标题】:ASP.net Response.Redirect on FileSystemWatcher eventFileSystemWatcher 事件上的 ASP.net Response.Redirect
【发布时间】:2010-09-09 08:09:22
【问题描述】:

我没有设法在新的 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

    }

【问题讨论】:

  • 你的 onChanged 方法是否被调用过?

标签: asp.net filesystemwatcher


【解决方案1】:

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

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

Page_Load 内部的某个地方启动了FileSystemWatcher。页面生命周期以Page_UnLoad 结束,运行页面生命周期的线程返回到线程池。更重要的是,页面已经渲染完成,没有什么可以改变了。

在稍后的某个时刻,可能是一秒钟,也可能是十分钟,FileSystemWatcher 会生成一个事件。页面很久以前就已经被浏览器渲染了,那么当你调用Response.Redirect时,你认为应该发生什么?由于响应已经发送到浏览器,所以什么都不会发生。

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

【讨论】:

  • 实际上我尝试创建这种机制 (FSW) 以捕捉 Flash 事件:用户单击我页面上的 Flash 按钮以上传文件。文件上传时,会调用一个aspx页面(图片通过form submit发送到这个页面)。我无法在该页面上使用重定向,所以我尝试使用 FSW。由于我无法修改 Flash - 我需要另一种解决方案来更改 Flash 事件的页面位置。
  • 我不确定我是否理解为什么您不能在将图片发布到的 aspx 页面上使用重定向?
  • 图片提交的页面不是Flash对象的页面。
  • 如果这是一个同步表单提交(不是一些 Ajax 提交),您应该能够在您发布到的页面中进行重定向。从哪里发帖并不重要。
  • 这是我开始的地方,但由于重定向在图像提交到的页面上不起作用,我开始寻找替代解决方案(FSW ...)。我是否应该假设,因为重定向不起作用,Flash 正在使用 Ajax 提交?重定向的其他解决方案还是只能由 Flash 对象启动?由于 Flash 部分不是我写的,所以我宁愿使用 asp.net 解决方案,也不愿尝试修改它。
【解决方案2】:

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

  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 进行比较。如果缓存日期较新,则响应。重定向用户。

如果您希望页面轮询服务器以检查更新,您还可以考虑将 asp:Timer 添加到页面和一些更新面板。

【讨论】:

  • FileSystemWatcher 将仅在 PageLoad 之后创建一个事件,因为它是页面本身启动文件上传(使用其中的 Flash 对象。请参阅我对 Ronald Wildenberg 的评论),因此 PageLoad 永远不会抓住这个事件。另一方面,使用 asp:Timer(我实际上从未遇到过)可能是一种解决方案(不是最优雅的解决方案 - 但我认为它应该可以工作)。
  • 我正在尝试使用 asp:Timer 这可能是一个解决方案。问题是导致 Flash 对象重新加载每个刻度,使其无法使用。
  • 如果你把 Timer 放在它自己的 UpdatePanel 中,它应该不会影响页面上的 flash 对象。此外,请确保页面上的任何其他 UpdatePanel 都设置为有条件地更新。试一试。
【解决方案3】:

恐怕这行不通——你的文件夹观察事件不是页面生命周期的一部分——你通常会运行一些其他线程或任务来处理 FSW,然后将你的状态保持在某个地方.那你可以说

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

希望有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    相关资源
    最近更新 更多