Web应用程序和多线程

3
我正在将一个桌面应用程序(WinForm)移植到一个 Web 应用程序(Java/Spring/JPA)上。问题很多,我有些困难...
现在的问题是线程问题!
在原始应用程序中,它从数据库中导出某些数据,并显示进度条以指示该过程的进度。
我想将此进度条移植到新的 Web 应用程序中。为此,我考虑使用 AJAX 并使用单独的线程运行数据导出。
主要关注点是:
  • 我是否采用了正确的方法?在 Web 应用程序中使用多线程会有什么问题吗?
  • 如果在导出过程中按下 F5 或刷新按钮,会发生什么?如何停止这个过程?
  • 如何定期更新进度条?我需要通过 ajax 调用服务器吗?

你有没有看过这里并尝试解决方案? - Luiggi Mendoza
3个回答

1

我主要是一个ASP.Net开发人员,但从我所知道的HTTP协议来看,这不是解决问题的方法。我见过很多相当聪明的解决方案,但最终变得清晰的是,HTTP协议根本没有设计成这样工作。

显然,您知道Flash或Silverlight应用程序可以做到这一点,但这也带来了自己的问题。

我个人更喜欢将所有奇怪的东西放在服务器上。过去,我曾经想出一种通过Web应用程序传递数千封电子邮件并更新用户进度的方法。我设计了一组表来充当队列。Web应用程序只需将任何交付请求放入此队列中,进度条将由检查队列中项目状态的请求确定。在后台运行的是一个Windows服务,它也会检查此队列,并实际负责传递邮件并设置每个项目的状态,以便完成或失败。

开发有点困难,因为Windows服务可能会有些棘手,但一旦它开始运行,它就非常平稳和可靠。根据您的情况,也许设置一个简单的定期任务每隔几分钟运行就能解决问题。


所以,如果我错了,请纠正我,我可以启动一个线程来执行“脏活”,然后从我的网页上进行定时请求以确定导出过程的进度... - davioooh
1
我不知道你在使用什么样的Web服务器,但在Web应用程序中生成线程总是让我感到不舒服。首先,在IIS中,如果在生成的线程内抛出未捕获的异常,它可能会导致整个Web服务器崩溃。我不确定这是否适用于Apache。 - Spencer Ruport

1
我不会直接为导出运行单独的线程。虽然这样做是理想的,但 Web 容器的能力将是一个限制因素。传统的 Java EE 应用服务器通常不鼓励为此生成线程(尽管您可以连接到线程池)。一些容器非常擅长释放阻塞线程,直到工作完成(例如使用 Jetty 和 Camel 的 Karaf),以便在导出发生时它们可以处理其他 Web 请求。但我的猜测是,您可能可以通过“开始导出”线程阻塞直到收到响应来解决问题。
这个导出需要多长时间?几秒钟还是几分钟?如果时间较短,我认为只需使用您喜欢的 Ajax 库将一个小的“等待”图标与小圆形旋转器放置在上面即可。
如果您真的想要一个真正的状态栏,定期刷新自己,那么是的,您必须以某种频率进行轮询。假设这可能是一个简单的请求,将从该作业的数据库表中加载作业的某种进度。

该过程可能需要几分钟时间,因此我认为阻塞主线程等待响应可能不是正确的方法。我可以通过异步请求启动该过程,并定期检查导出进程的进度... - davioooh
即使从浏览器的角度进行异步请求,服务该请求的服务器线程仍将在后台阻塞。此时,它将无法处理其他HTTP请求。如果您可以接受这种情况,那么这是最简单的方法,但如果您想要释放它,那么就应该涉及线程池,并通过Executor委托给Runnable。 - Jonathan W

0

在这里找到我的答案

我是否遵循了正确的方法?在Web应用程序中使用多线程会有问题吗?

-是的,您走在了正确的道路上。在Web应用程序中使用多线程没有任何问题,就像在WinForm中一样容易。您将使用AJAX调用而不是使用Dispatcher更新UI,并且通过JavaScript DOM操作进行操作。

如果在导出过程中按下F5或刷新按钮,会发生什么?我该如何停止这个过程?

-不幸的是,没有简单的方法。标准的方法是,在完成此类处理并且用户按下F5时,您将使用JavaScript显示对话框并通知用户作业仍在运行。如果用户仍然想要刷新,则必须向服务器发出另一个请求以取消任务(您需要在某个地方存储线程ID或取消令牌以取消任务)。

如何定期更新进度条?我是否需要通过ajax向服务器发出调用?

-通常的标准方式是显示一个加载图像。如果你想显示一个上下文相关的进度条,那就意味着你需要进行轮询。这里有一个Dino Espito的例子。虽然它是在ASP.NET中,但你可以理解其基本原理。 Dino Espito


当你说“你将通过JavaScript显示对话框并通知用户作业仍在运行”时,你的意思是拦截“刷新事件”吗? - davioooh
是的,您可以通过在JavaScript中处理按键事件轻松完成它。 - Anand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接