在WebForms中使用Rx执行长时间运行的任务

时间:2013-09-10 23:35:37

标签: c# .net visual-studio-2012 webforms system.reactive

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

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

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

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

我认为目前的实施非常糟糕,但有效:

  1. 用户通过FileUpload控件
  2. 选择.csv文件
  3. 点击页面上的按钮以启动流程
  4. 然后创建两个列表并存储在会话密钥中
  5. 创建后台线程并接收长时间运行的void方法,该方法接收两个列表并在每次迭代时向它们添加新消息。线程本身也存储在单独的会话变量
  6. 页面上启用了计时器,间隔设置为1000(一秒)
  7. 当计时器滴答时,gridviews将与列表数据绑定,更新界面
  8. 在Page_Load上,检查线程变量以查看它是否仍然存活,如果没有,则禁用定时器。
  9. 有没有办法让Rx在没有会话变量的情况下使用Rx?我认为可以使用.Scan方法来组合消息的整个历史记录(这就是为什么我asked this),使点击触发器启动所有内容并勾选实际接收的触发器消息。然后,订阅代码将结果简单绑定到gridviews。由于WebForms中的数据源不保留旧值,因此需要在每次滴答时刷新所有内容。

    我实际上可以构成大部分内容,但是当委托者解雇绑定网格时,没有任何事情发生,因为这一切都发生在其他线程上。我无法看到控制所有这些内容的方法,因为每个Web应用程序请求都是在未知的线程上启动的。有没有办法模拟在此上下文中WPF或WinForms应用程序上发生的用户交互,以使其工作?

2 个答案:

答案 0 :(得分:2)

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

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

我知道这种方法需要大量的重新考虑因素。在消费者刚刚进行全面刷新调查的情况下,我只是没有看到切换到RX可观察源的重点。

答案 1 :(得分:1)

抱歉文章/书中缺少网页内容。在过去的几年里,我几乎完全使用WPF / Silverlight for UI。就在最近,我已经启动了一个项目,这是一个Web项目,我也有一个长时间运行的查询,将数据反馈给用户,这肯定比WinForm / WPF / Silverlight要难得多。

我正沿着SignalR路走下去,但即便如此,似乎与Rx存在一些摩擦。我遇到的主要问题是Rx没有阻塞,所以我调用的SignalR方法很快完成,然后连接被切断。如果我能弄清楚如何做好,我会在这里发布模式。

但你知道你并不孤单......