1

我刚刚阅读了这篇文章的全部内容,我正在努力编写代码,试图在 WebForms 页面中实现一个长时间运行的任务并使用 Rx 来检索值。我开始认为这是不可能的,但我认为无论如何提出这个问题是有建设性的,因为关于 Rx 的信息非常有限,更不用说 Rx 和 WebForms (还没有找到一篇提到两者的帖子/文章) )。

我想要实现的实际上相当简单。我有一种从 csv 文件中读取数据并对其进行大量处理的方法。目前,它填充了两个列表,一个带有“成功消息”,另一个带有“错误消息”。目前的设计确实很糟糕,但请耐心等待这个......

然后将这两个列表绑定到 aspx 中的两个不同的网格视图。

这里的问题是任务需要相当长的时间才能完成,我们不想让用户等待很长时间而没有任何反馈。

在我看来,当前的实现非常糟糕,但有效:

  1. 用户通过FileUpload控件选择 .csv 文件
  2. 在页面上单击一个按钮以启动该过程
  3. 然后创建两个列表并将其存储在会话密钥中
  4. 创建一个后台线程并接收长时间运行的 void 方法,该方法反过来接收两个列表并在每次迭代时向它们添加新消息。线程本身也存储在单独的会话变量中
  5. 页面开启定时器,间隔设置为1000(一秒)
  6. 当计时器计时,gridviews 与列表数据绑定,更新界面
  7. 在 Page_Load 上,检查线程变量以查看它是否还活着,如果没有,则禁用计时器。

有没有办法以某种方式使用没有会话变量的 Rx 来完成这项工作?我认为可以使用该.Scan方法来组装消息的整个历史记录(这就是我问这个的原因),使单击触发器启动一切,并单击触发器以实际接收消息。订阅代码将是结果到网格视图的简单绑定。由于 WebForms 中的数据源不保留旧值,因此每次滴答时都需要刷新所有内容。

我实际上可以编写大部分内容,但是当委托触发绑定网格时,什么都没有发生,因为这一切都发生在其他线程上。我看不到控制这一切的方法,因为对 web 应用程序的每个请求都是在未知线程上启动的。有没有办法模拟在这种情况下发生在 WPF 或 WinForms 应用程序上的用户交互以使其工作?

4

2 回答 2

2

我会尽力回答。IEnumerable 和 IObservable 之间的主要区别在于 pull 与 push。也就是说,IEnumerable 仅在请求一个值时返回下一个值,而 IObservable 通过 立即推出下一个值.OnNext()。这表明 IObservable 与轮询客户端不兼容,后者基本上是基于拉取的。

对我来说,RX 在该场景中有意义的唯一方法是使用 websockets,它支持来自服务器的基于推送的通信。(SignalR是 ASP.Net 的一个很好的“官方”websockets 集成。)这将允许您将服务器数据源作为订阅者连接到后台线程的 IObservable。观察者线程会立即接收到新事件,然后可以立即将它们推送到客户端进行显示。

我知道这种方法需要大量的重构。我只是看不出切换到 RX 可观察源的意义,在这种情况下,消费者只是在进行完全刷新的轮询。

于 2013-09-11T00:59:29.427 回答
1

很抱歉文章/书中缺少网络内容。在过去的几年里,我几乎只在 UI 上使用 WPF/Silverlight。就在最近,我开始了一个 Web 项目,并且我也有一个长时间运行的查询,可以将数据滴回给用户,这肯定比 WinForm/WPF/Silverlight 更难做到。

我正在走 SignalR 的道路,但即使这样似乎也与 Rx 有一些摩擦。我面临的主要问题是 Rx 不会阻塞,所以我调用的 SignalR 方法很快完成,然后连接被切断。如果我能弄清楚如何做好,我会在这里发布要使用的模式。

但只是为了让你知道你并不孤单......

于 2013-09-11T16:32:35.143 回答