【问题标题】:How do you measure the progress of a web service call?您如何衡量 Web 服务调用的进度?
【发布时间】:2010-09-13 05:22:26
【问题描述】:

我有一个 ASP.NET Web 服务,它可以完成一些繁重的工作,比如一些文件操作,或者从一堆水晶报表生成 Excel 表格。我不想被调用这个 web 服务阻塞,所以我想让 web 服务调用异步。另外,我想从网页调用这个 Web 服务,并且想要一些机制来让我继续轮询服务器,这样我就可以在屏幕上显示一些进度指示器,比如文件的数量已处理。请注意,我不想要 Web 方法调用完成时的通知,而是想要实时进度状态。我该怎么办?

【问题讨论】:

  • 我们都在想,“为什么 Web 服务不自动执行此操作?”当我们说它们很烂时,这就是我们的意思。您必须自己构建所有这些东西。

标签: ajax web-services asp.net-ajax asynchronous


【解决方案1】:

在服务器上编写一个单独的方法,您可以通过传递已安排的作业的 ID 来查询该方法,该方法返回 0-100(或 0.0 和 1.0,或其他)之间的近似值.

例如在 REST 风格中,您可以向 http://yourserver.com/app/jobstatus/4133/ 发出 GET 请求,这将返回一个简单的“52”作为 text/plain。然后你只需要每隔(秒?两秒?十秒?)查询一次,看看它有多远。

您如何在后端实际完成监控很大程度上取决于您的流程是什么以及它是如何工作的。

【讨论】:

    【解决方案2】:

    我认为 XML Web 服务很慢,所以创建多个方法并轮询进度会非常慢,并且会在服务器上产生巨大的负载。我不会在生产环境中这样做。我发现数据库轮询存在相同(但更小)的问题。

    尝试 SOAP 扩展。它实现了一个事件驱动的模型。见Adding a Progress Bar to Your Web Service Client Application on MSDN

    【讨论】:

      【解决方案3】:

      您也可以use SoapExtensions 通知您的客户下载/处理进度。然后服务器可以向客户端发送事件。如果您不使用客户端,则无需更改任何内容。

      在您的客户端中允许这样的事情:

      //...
      private localhost.MyWebServiceService _myWebService = new localhost.MyWebServiceService ();
      _myWebService.processDelegate += ProgressUpdate;
      _myWebService.CallHeavyMethod();
      //...
      
      private void ProgressUpdate(object sender, ProgressEventArgs e)
      {
        double progress = ((double)e.ProcessedSize / (double)e.TotalSize) * 100.00;
        //Show Progress...
      }
      

      【讨论】:

        【解决方案4】:

        让初始的“开始报告生成”Web 服务调用在某个任务池中创建一个任务,并返回调用者任务的 ID。

        然后,提供另一种返回给定 taskId 的“完成百分比”的方法。

        提供第三种方法,返回已完成任务的实际结果。

        【讨论】:

          【解决方案5】:

          最简单的方法是让 Web 服务根据调用进度更新数据库中的字段,然后创建一个查询该字段并返回值的 Web 服务。

          【讨论】:

          • 如果您使用数据库,最好创建一个内存表。没有意义在琐碎的任务上浪费磁盘 I/O。
          • 它不一定是微不足道的,您可以将其用作审计/日志表。表中的一列可以存储 or 状态,其他列可以存储开始/结束时间、呼叫者 ID 和结果值(失败/成功等)。
          【解决方案6】:

          使 Web 服务返回某种任务 ID 或会话 ID。使用该 ID 创建另一个 Web 方法来查询,它返回所需的信息(完成百分比、文件列表等)。每隔一段时间从客户端轮询此方法。

          使用数据库存储进程信息,如果您在 Web 服务的内存中执行此操作,这将无法在 Web 场环境中很好地扩展,因为该任务可能会在另一台服务器上运行,而不是您所在的服务器投票。

          编辑:我刚刚看到另一个类似的答案,并对其发表评论。评论者是对的 - 您可以使用内存表来避免磁盘操作,但仍然使用单独的数据库服务器。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多