0

我有一个长期运行的操作,您可能会在我的另一个问题中阅读(供您参考,这里是firstsecond)。

在整个交易开始时,项目公开了一个表单,用户应在该表单中指定有关 XML 文件的所有必要信息并上传 XML 文件本身。在该方法中,所有用户输入数据都被捕获并转到处理此类文件之王的 WCF 服务。控制器仅获得此类处理的任务 ID。然后用户被重定向到进度条页面并定期检索任务完成状态,刷新进度条。

所以我的问题来了。处理 XML 文件时如果结束,如何获取结果并将其显示给用户?

我知道 HTTP 是无状态协议,但是在这种情况下有 cookie 机制可以提供帮助。当然,我可能只是将处理结果保存到一些临时的地方,比如 WCF 服务器中的一个静态类,但是服务负载很高,所以它会吃掉所有提供的内存。

换句话说,我想将任务传递给 WCF 服务(使用 netNamedPipeBinding)并尽可能快地接收结果。我想将临时保存结果转义到某个缓冲区并等到客户端将其收集回来。


据我所知,不是在服务端而是在客户端使用临时缓冲区:

using (XmlProcessingServiceClient client = new XmlProcessingServiceClient())
{
    client.AnalyzeXmlAsync(new Task { fileName = filePath, id = tid });
    client.AnalyzeXmlCompleted += (sender, e) =>
    {
        System.Web.HttpContext.Current.Application.Lock();
        // here is I just use single place for all clients. I know it is not right, it is just for illustrating purposes.
        System.Web.HttpContext.Current.Application["Result"] = e;
        System.Web.HttpContext.Current.Application.UnLock();
    };
}
4

4 回答 4

3

我建议您使用SignalR 集线器来解决您的问题。您有一种方法可以直接调用客户端上的方法来通知操作已完成。并且无需处理实施此类策略时存在的实际基础设施问题即可发生这种情况。Plus SignalR可轻松插入 asp.net MVC 应用程序。

于 2012-11-08T06:15:50.910 回答
0

老实说,我并没有真正了解有关 wcf 服务器和其他东西的部分,但我想我可以给你更多抽象的答案。为了确定:

  1. 您有一个包含一些字段 + 文件上传的表单
  2. 用户填写表单并提供 XML 文件
  3. 您将 XML 文件发送到处理它的 WFC 服务
  4. 同时显示一个更新的进度条
  5. 完成后显示结果

如果这不是您想要的,或者这不是您的问题,您可以跳过我的回答,否则请继续阅读。

开始之前:第 3 步有点模糊:这可能意味着我们将数据发送到服务并等待它返回结果,或者我们将数据发送到服务并且我们不等待它返回结果。

情况一:

  1. 在视图中创建包含所有必填字段的表单
  2. 在您的控制器中创建一个处理回发的操作。
  3. 该操作会将数据发送到服务,当服务返回结果时,您的操作将呈现一个带有结果的视图。
  4. 在提交按钮上,您在点击事件上添加一个 javascript。这将触发对某些服务器端代码的 ajax 调用,该代码将返回进度。
  5. javascript显示某种具有正确进度的状态栏,并每x秒重复一次
  6. 当控制器完成时,它将显示结果

情况2:

  1. -
  2. -
  3. 将数据发送到服务后,控制器会显示一个带有进度条的视图。
  4. 我们在文档就绪时添加了一个 javascript 事件,它检查 xml 文件的状态并更新进度条。(与情况 1 中步骤 4 中的 onclick 事件相同)
  5. 当进度条达到 100% 时,它将重定向到显示结果的不同页面

这回答了你的问题了吗?

此致,

BHD

于 2012-11-03T08:45:34.363 回答
0

我不确定这是否是最好的解决方案,但我能够做类似的事情。这是一般设置:

  1. 控制器 A 使用要执行的操作的参数初始化一个新类,并传递用户的会话对象
  2. 新类在后台线程中调用了一个方法,该方法在用户会话进行时更新了用户会话
  3. 控制器 B 具有 json 方法,当由客户端 javascript 调用时,检查用户的会话数据并返回最新进度。

线程指出以这种方式使用会话对象是不好的,但我相信您可以使用线程安全存储方法(如 sql 或临时文件)执行类似的操作。

于 2012-11-08T00:03:06.917 回答
0

如果这是您的想法, netNamedPipeBinding将不适用于跨机器通信。

如果您想在 IIS 上托管我们的服务,那么您将需要使用 HTTP 作为其传输协议的绑定之一。查看允许两个端点发送消息的双工服务。这样,服务器可以随时向客户端发送消息。您可以为进度报告创建一个回调接口。如果任务需要花费大量时间来完成,那么通过 HTTP 报告进度的开销可能是可以的。

如果您想通过 HTTP 与 Silverlight ( PollingDuplexHttpBinding ) 一起使用双工通信,还可以查看构建和访问双工服务

最后,您可以寻找 ASP.NET 的Comet实现。在 CodeProject 中,您至少会有一对(CometAsyncPokeIn)。

于 2012-11-07T22:50:14.033 回答