Reputation: 8221
I've just read the entirety of this article and I'm struggling with the code, trying to implement a long running task in a WebForms page and using Rx to retrieve the values. I'm starting to think it is kind of impossible, but figured it would be constructive to ask this anyways since there is very limited info on Rx, much less Rx alongside WebForms (haven't found a single post/article that referred to both).
What I would like to achieve is fairly simple actually. I have a method that reads data from a csv file and does a bunch of processing on it. Currently, it populates two lists, one with "success messages" and the other with "error messages". The current design is admittedly quite bad, but bear with me on this one...
These two lists are then bound to two different gridviews in the aspx.
The problem here is that the task takes quite a while to complete, and we didn't want to make the user wait a long time without any feedback.
The current implementation is very lousy in my opinion, but works:
Is there a way to make this work using Rx without session variables somehow? I thought it would be possible to use the .Scan
method to assemble the whole history of messages (this is why I asked this), making the click the trigger to start everything and the tick the trigger to actually receive the messages. The subscription code would then be a simple bind of the results to the gridviews. Since datasources in WebForms do not retain old values, this is needed to refresh everything at every tick.
I could actually compose most of this, but when the delegates fired to bind the grid, nothing happened because that was all happening on other threads. I can't see a way to control all this seeing as every request to the webapplication is started on an unknown thread. Is there a way to simulate the user interaction that happens on a WPF or WinForms application in this context to make this work?
Upvotes: 1
Views: 539
Reputation: 10783
Sorry about the lack of Web stuff in the article/book. I have been working almost solely with WPF/Silverlight for UI for the last few years. Just recently I have started a project that is a Web project and I too have a long running query that trickles data back to the user, and it sure is a lot harder than WinForm/WPF/Silverlight to do.
I am going down the SignalR path, but even that seems to have some friction with Rx. The main problem I have faced is that Rx doens't block so the SignalR method I call completes very quickly and then the connection gets severed. If I can figure out how to do it well, I will post the pattern to use here.
But just so you know you are not alone....
Upvotes: 1
Reputation: 102793
I'll take a crack at answering. The main difference between IEnumerable and IObservable is pull vs push. That is, IEnumerable only returns the next value when one is requested, whereas IObservable pushes the next value out immediately via .OnNext()
. This suggests that IObservable is not compatible with a polling client, which is fundamentally pull based.
To me, the only way RX would make sense in the scenario would be to use use websockets, which enables push-based communication from the server. (SignalR is a good "official" websockets integration for ASP.Net.) This would allow you to connect the server data source as a subscriber to the background thread's IObservable. The observer thread would receive new events immediately, and could then immediately push them to the client for display.
I understand that this approach would require a substantial re-factor. I just don't see the point in switching to an RX observable source, in a case where the consumer is just doing a full-refresh poll.
Upvotes: 2