C#中耗时程序的建议

3
我使用Delphi开发了一个程序,其中包含许多特性,涉及到大量浮点数的数据库读取和计算。在这些计算结束后,程序会显示一个结果屏幕。这些计算需要一些时间才能完成:今天,大约需要5到10分钟才能最终显示结果屏幕。
现在,我的客户要求将这个程序转换成.Net版本,因为我其他的程序几乎都已经转换成了.Net。但是我担心这个耗时的计算过程不适合Web场景,程序可能会导致用户遇到某种超时错误。
因此,我想请教一些关于如何处理这种过程的技巧或建议。最初,我考虑调用一个本地可执行文件(甚至可以是我的初始Delphi程序,以控制台方式运行),并在一段时间后在Web页面上显示结果屏幕。但是,我再次担心这可能不是最好的方法。
4个回答

4

使用外部进程是一个合理的方法。你可以在ASP.NET进程内部启动一个线程(例如,只需使用new Thread()),这也可以工作,但是在处理进程回收和池化方面存在一些问题,这可能会使这个过程更加困难。对我来说,简单地启动一个外部进程,然后使用一些Ajax轮询来检查它在浏览器上的状态似乎是一个不错的解决方案。


harding: 这种方法的问题在于,如果你有足够多的用户触发计算,可能会导致大量运行线程。更好(更可伸缩)的方法是将请求放入队列中,并让工作进程处理这些请求。 - Toad
@Toad:没错,我想这取决于预期的工作量。 - Dean Harding
@Toad:但是我可以在表格上设置一个标志,阻止其他用户启动新的计算线程,直到第一个线程结束,不是吗?我会尝试这个想法,测试一下,然后再回来投票答案... - SoftwareSculptor
@softwaresculptor,你可以这样做,但这并不是很用户友好的。有人必须等待他们的轮到来临,并在一段时间后重试,也许会发现该插槽已被其他人占用。无论如何,对于低使用率的网站,启动线程的方式是可以接受的。我只是指出了可能会发生的问题。 - Toad

3
值得一提的是,一些在线服务(例如执行文件转换等可能需要几分钟时间的服务)使用的另一种模式是让用户输入电子邮件地址,并在完成后通过电子邮件发送结果。这样,如果他们意外关闭了浏览器或者花费的时间比预期长,都不会有大问题。
我曾经采用的另一种方法基本上与Dean建议的相同-启动进程并拥有一个自动刷新的状态页面,一旦完成,状态将包括指向结果的链接。

0
如何呢:
  • 创建一个 Web 服务来获取/计算。
  • 设置 超时,以防止过期。

YourService.HeavyDutyCalculator svc = new YourService.HeavyDutyCalculator(); svc.Timeout = 10 * 1 * 1000; //表示10分钟,10 分钟 x 1 秒 x 1000 毫秒 Service.CalculateResult result = svc.Calculate();

请注意,如果您希望它无限运行,可以将其设置为-1。

MSDN:

将 Timeout 属性设置为 Timeout.Infinite 表示请求不会超时。即使 XML Web 服务客户端可以将 Timeout 属性设置为不超时,Web 服务器仍然可以在服务器端导致请求超时。

  • 在您的网页中调用该 Web 方法
  • 放置等待/进行中图像
  • 注册 Web 方法 OnComplete 事件;并在完成后显示结果。

您还可以在 web.config 中更新超时时间:

<httpRuntime useFullyQualifiedRedirectUrl="true|false"
             maxRequestLength="size in kbytes"
             executionTimeout="seconds"
             minFreeThreads="number of threads"
             minFreeLocalRequestFreeThreads="number of threads"
             appRequestQueueLimit="number of requests"
             versionHeader="version string"/>

让用户静静地等待十分钟,希望会发生什么吗?我不确定这是 Web 应用程序的最佳解决方案。长时间运行的任务应该在单独的线程中完成,或者更好的方法是将其放入队列中,工作人员会选择并进行处理。 - Toad
@Toad:即使您正在使用线程,您如何计划处理用户的10分钟等待状态?有一步是说在上面放置一个等待/进行中的图像,可以处理这个问题。此外,异步Web方法调用在内部处理线程功能; Web方法的异步实现释放工作线程以处理其他可以由Web方法执行的并行任务;这确保了线程池的最佳利用。此外,“排队还是不排队”不是问题,唯一减少时间的方法是缩短数据处理时间。 - KMån

0
无论你做什么,你都需要一个进度条或其他状态指示给用户。用户已经习惯了在几秒钟内加载的网页,即使你事先告诉他们,他们也不会意识到他们必须等待整整10分钟才能看到结果。

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