【问题标题】:Where to store progress information in ASP.Net web application在 ASP.Net Web 应用程序中存储进度信息的位置
【发布时间】:2011-07-21 04:45:12
【问题描述】:

我正在创建一个页面,用于获取上传的文本文件并将它们构建为多个 PDF。它们只是从 Excel 导出的。文件中的每一行对应一个需要创建的新 PDF。

无论如何,一旦文件上传,我想开始处理它们,但我不希望用户必须留在页面上,甚至仍然打开他们的会话。例如,他们可以关闭浏览器并在 10 分钟后返回,登录,进度信息将显示 112/200 个文件已处理或其他内容。不过会比这快很多。

真的有两个问题,我怎样才能将此处理作业传递给在页面关闭时将继续运行的东西(处理程序?线程?),并在作业开始后立即返回(所以浏览器不是t 停止)?其次,我在哪里可以存储这些信息,以便当用户返回页面时,他们可以看到当前的进度。

我意识到我不能使用会话,并且由于它每秒会处理一个文件,所以我真的不想每秒更新一个数据库。有什么办法可以做到这一点吗?有可能吗?

【问题讨论】:

标签: c# asp.net webforms


【解决方案1】:

我使用上面 asstander 提供的链接解决了这个问题。我只是在 HttpContext.Application 中创建一个对象来存储进度变量,然后设置在新线程中进行处理的方法。

// Create the new progress object
BatchProgress bs = new BatchProgress(0);
if(Application["BatchProgress"] != null)
{
    // Should never happen
    Application["BatchProgress"] = bs;
}
else
{
    Application.Add("BatchProgress","bs");
}

//Set up new thread, run batch is the method that does all the processing.
ThreadStart ts = new ThreadStart(RunBatch);
Thread t = new Thread(ts);
t.Start();

然后在线程启动后返回,我可以使用 jQuery 定期获取 Application["BatchProgress"] 对象。在我的线程结束时,BatchProgress 对象的状态设置为“完成”,然后当 jQuery 查询它时,它会看到完成状态并从应用程序中删除进度对象。

【讨论】:

  • 这似乎在测试中有效,但这里有两个大问题。第一个是如果一段时间内没有人访问您的站点,您的处理批次可能会被终止。第二个是 HttpContext.Application() 项目由您站点的所有用户共享​​>,因此一个用户最终可能会覆盖另一个用户的批处理引用并查看他们的进度信息。相反,您需要构建一个 Windows 服务并与之对话。
  • 哦,我不知道批次会被杀死,这有点令人担忧。但是,批处理引用将不允许覆盖,使用页面所需的功能仅在 Application["BatchProgress"] 等于 null 时可用,否则将从页面中删除服务器控件并显示 BatchProgress。只有 1 个用户在管理站点上使用它,所以我一次只需要 1 个批次。该批次将每周运行。我的处理批次多久会被终止?
  • 这取决于 IIS 中的设置,以及您的网站获得的流量。我认为默认值是 20 分钟的空闲时间,但我的记忆对确切的时间限制很模糊。之后,托管该站点的应用程序池将关闭。因此,如果您在公共互联网上什至有一个受欢迎的网站,那就没问题了。如果这是在它自己的应用程序池中,并且每周只有一个人访问它,那么您可能会遇到问题。
  • 好吧,我希望这不会超过 20 分钟,但很可能没有人会访问该网站几个小时,它确实为其他管理员提供了其他功能,但显然没有全部使用时间。感谢您提供的信息,我将改为查看 Windows 服务。
猜你喜欢
  • 2010-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多