Do Rx Extensions give me functionality similar to jQuery.Deferred? - c#

I have some functionality that needs to be async in my C# app. It's a fairly simple workflow so I don't need to get fancy with it I basically need the equivalent of jQuery.Deferred.
My method should return an object that people can attach success and failure handlers to. Either the success or failure handler will fire exactly once. I also need a way to trigger the success/fail when the async process completes.
So I want something like this:
var asyncTask = ReadSomeStatsFrom("a-really-big-file.txt");
asyncTask.OnSuccess += (stats) => Console.WriteLine("Completed " +stats.ToString());
asincTask.OnFail += (err) => Console.WriteLine("Uh Oh "+err.ToString());
//return control to the calling method and go on to do other stuff
Yes I can create threads and simulate this sort of thing as I did last time I needed this functionality years ago but isn't there' new stuff to make this all neater by now? I've been hearing about Rx and it seems to be addressing similar problem areas (and obviously a lot more).
So question 1: Am I on the right track in looking into Rx for this functionality? If not what I should look into.
and question 2: How would the above example look with rx, including actually signifying that the task succeeded or ended inside ReadSomeStatsFrom()

Rx seems perfectly well suited for your needs.
If ReadSomeStatsFrom can be written synchronously then try this:
Observable
.Start(() => ReadSomeStatsFrom("a-really-big-file.txt"))
.Subscribe(
stats => Console.WriteLine("Completed " + stats.ToString()),
err => Console.WriteLine("Uh Oh " + err.ToString()));
I agree that TPL may be a good fit too, but Rx can be more expressive than TPL in many ways.

Have a look at the Task Paralel Library too. It ships with the clr, and it is abetter fit for your needs. Rx is for streams of events primarily, not single ones.
I have seen a sample where an async io (your file read) is wrapped in a tpl task almost directly, but that could be a 4.5 feature.

The Task Parallel Library is what you are looking for, the link here http://msdn.microsoft.com/en-us/library/ee372288.aspx will explain the features of the library.
Specifically, you want to look at handling your response as a continuation which is discussed on the page.

Related

Is there a `when()` statement or some equivalent in C#?

Is there maybe something like a "when" statement in C#?
The reason I want this is because an if statement only checks once if a certain property is true at a particular time, but I want it to wait until the property is true.
Anybody know something I can do in C# that would be similar to a "when" statement?
What you want is SpinWait
e.g. SpinWait.SpinUntil(() => condition);
It will sit there until it either times out (with your specified timeout) or the condition is met.
There is no when control statement, but there are two options which might meet your needs:
You can use a while(predicate){} loop to keep looping until a condition is met. The predicate can be any expression which returns true/false - as long as the condition is true, it will loop. If you just want to wait without consuming too much CPU, you can Sleep() the thread within the loop:
while(name == "Sebastian")
{
// Code to execute
System.Threading.Thread.Sleep(1000);
}
If you property is a numeric range, you could use a for loop, but that doesn't sound like what you want.
If you want to deal with an asynchronous world than you may be should look at the library Rx.NET. Let's look at the simple example: suppose you want to read strings from the console and when user inputs word "hello" you need to print "world" in the response. This simple example can be implemented as follows:
var inputLines = new Subject<string>();
inputLines.Subscribe(info =>
{
if (info == "hello")
Console.Out.WriteLine("world");
});
while (true)
{
var line = Console.In.ReadLine();
inputLines.OnNext(line);
}
So, there are explicit when action, that we pass in the Subscribe(...) function.
In this simple example usage of Rx.NET is obviously unnecessarily and you shouldn't do it. But in more complex scenarios this is a very helpful library. You can see, that with Reactive Extensions you split the logic of your application from the main event-pool, where you can want to do some other work, not related to the application logic. Also, there is high flexibility that you can get with this library, because it's very dynamic - you can subscribe and unsubscribe different events in run-time at any time.
You can notice, that there is another way to solve my example in the event-based paradigm. We can simply use built-in events like this:
public static event EventHandler<string> InputEvent;
public void Run()
{
InputEvent += (sender, line) => {
if (line == "hello")
Console.WriteLine("world");
};
while (true) {
var line = Console.In.ReadLine();
InputEvent?.Invoke(this, line);
}
}
And this is a right point, sometimes you can replace Reactive Extensions with simple events because they are connected. But when you need to build a complex pipeline from many event sources and using many different tightly coupled actions, then Reactive Extensions allow you to nicely build this pipeline in the very declarative way.
You can use 'async' and 'await' to wait unit a certain 'Task' is complete. 'await' is somewhat similar to the 'when' statement you need. Only it pauses the current 'Task' until the awaited 'Task' finished with any result not just when an expression becomes 'true'. See also TaskCompletionSource.
What are you trying to achieve here? Are you running a synchronous process or are you waiting for something asynchronous to happen?
If you're synchronous then while is probably the correct solution:
var result = 0;
while(result != 6)
{
result = RollADie();
Console.WriteLine($"I rolled a {result}");
}
Console.WriteLine("At last, a six!");
But - if you're waiting for something asynchronous to happen then a different solution is called for. An asynchronous scenario is where you want your code to 'hang around and wait, doing nothing' until the condition is fulfilled.
In that case the modern C# solution is asynchronous programming using the async and await keywords, along with the Task class (and it's generic cousin Task<TResult>). That's probably a bit deep to go into here, but here's a pretty good primer.
What's important is that you don't use a solution based on while in order to deal with asynchronous processes. You'll just send the CPU spinning in circles, chasing it's own tail so to speak, when really you want to say "now stop working on this until X happens". Also, avoid any solution based on while combined with Thread.Sleep for related reasons.

How would I write this code with Reactive Programming?

I just started messing around with reactive programming, and I know just enough to write code but not enough to figure out what's happening when I don't get what I expect. I don't really have a mentor available other than blog posts. I haven't found a very good solution to a situation I'm having, and I'm curious about the right approach.
The problem:
I need to get a Foo, which is partially composed of an array of Bar objects. I fetch the Bar objects from web services. So I represented each web service call as an IObservable from which I expect 0 or 1 elements before completion. I want to make an IObservable that will:
Subscribe to each of the IObservable instances.
Wait for up to a 2 second Timeout.
When either both sequences complete or the timeout happens:
Create an array with any of the Bar objects that were generated (there may be 0.)
Produce the Foo object using that Bar[].
I sort of accomplished this with this bit of code:
public Foo CreateFoo() {
var producer1 = webService.BarGenerator()
.Timeout(TimeSpan.FromSeconds(2), Observable.Empty<Bar>());
var producer2 = // similar to above
var pipe = producer1.Concat(producer2);
Bar[] result = pipe.ToEnumerable().ToArray();
...
}
That doesn't seem right, for a lot of reasons. The most obvious is Concat() will start the sequences serially rather than in parallel, so that's a 4-second timeout. I don't really care that it blocks, it's actually convenient for the architecture I'm working with that it does. I'm fine with this method becoming a generator of IObservable, but there's a few extra caveats here that seem to make that challenging when I try:
I need the final array to put producer1 and producer2's result in that order, if they both produce a result.
I'd like to use a TestScheduler to verify the timeout but haven't succeeded at that yet, I apparently don't understand schedulers at all.
This is, ultimately, a pull model, whatever gets the Foo needs it at a distinct point and there's no value to receiving it 'on the fly'. Maybe this tilts the answer to "Don't use Rx". To be honest, I got stuck enough I switched to a Task-based API. But I want to see how one might approach this with Rx, because I want to learn.
var pipe = producer1
.Merge(producer2)
.Buffer(Observable.Timer(TimeSpan.FromSeconds(2), testScheduler))
.Take(1);
var subscription = pipe
.Select(list => new Foo(list.ToArray())
.Subscribe(foo => {} /* Do whatever you want with your foo here.*/);
Buffer takes all elements emitted during a window (in our case in two seconds), and outputs a list.
If you want to stick with your pull model, instead of a subscription you could do:
var list = await pipe;
var foo = new Foo(list.ToArray());
//....

Reactive Extensions - Correct way to observe a Javascript call into C# wrapper

I am developing a C# WinForms application that contains a web browser control. The application contains a "scripting bridge" class that allows Javascript code to call into the web browser control (I need to know when certain functions are called in the JS code in order to perform some action in the WinForms application). Most of these operations are asynchronous because when I launch a request from the WinForms application, it will typically perform an ajax request within the JS code (not the C# code). Since this is an asynchronous operation, I was trying to come up with a better/easier way to manage the subscriptions/timeouts/error handling, etc. for these asynchronous events. I came across Reactive Extensions and decided to try it out.
I'm trying to determine if I am doing this correctly or not. I'm trying to wrap my head around Reactive Extensions. It's difficult to find simpler examples on the net for a lot of the Observable extension methods. Here is what I am doing right now:
public void SetupObservable()
{
IConnectableObservable<string> javascriptResponseObservable = Observable.Create<string>(
(IObserver<string> observer) =>
{
observer.OnNext("Testing");
observer.OnCompleted();
return Disposable.Create(() => Console.WriteLine("Observer has unsubscribed"));
})
.Timeout(DateTimeOffset.UtcNow.AddSeconds(5))
.Finally(() => Console.WriteLine("Observable sequence completed"))
.Publish();
IObserver<string> testObserver = Observer.Create<string>(
(value) => Console.WriteLine(value),
(e) => Console.WriteLine("Exception occurred: " + e.Message),
() => Console.WriteLine("Completed")
);
IDisposable unsubscriber = javascriptResponseObservable.Subscribe(testObserver);
}
// The following will be executed later (once the ajax request is completed)...
// Fire the event and notify all observables. If it took too long to get this point then the sequence will timeout with an exception.
public void OnSomeJavascriptFunctionCall()
{
// Somehow get the javascriptResponseObservable object...
javascriptResponseObservable.Connect();
}
I feel like I am doing this the wrong way or that there is a better way to accomplish this. For example, how do you retrieve the IObservable that was created earlier so that you can call more methods on it? Would I have to persist it in the class or somewhere else? It seems like a lot of the examples don't do this so it seems like I am doing something fundamentally wrong. Also, if several observers are subscribing to the IObservable from different classes, etc., again, how do you keep track of the IObservable? It seems like it needs to be persisted somewhere after it is created. Is there a Observable.GetExistingObservable() method of some sort that I am missing?
I feel like I am doing this the wrong way or that there is a better way to accomplish this.
Wrong is always a point of view, but I would argue, yes there is a better way to solve what you are doing.
I assume that your JavaScript bridge has some sort of way of raising events? And this is how it is able to call-you-back? If so, they you will want to leverage that call back and bridge that to Rx using either Observable.Create, Observable.FromEvent* or another Rx factory method.
That would be your first step, then you would need to pass your "commands" to your JS layer. This is where you would need to remember to subscribe to your callback sequence before you issue the command to mitigate any race conditions.
It is difficult to help any more, as you only show Rx code that seems to serve no purpose except trying to understand Rx, and no code that shows what you are trying to achieve in the C#-to-Js bridge. Please provide a "Minimum Complete Verifiable Example" - https://stackoverflow.com/help/mcve

How do I push an entity onto an Rx Observable?

I have a class that is going to be responsible for generating events on an frequent but irregular interval, that other classes must consume and operate on. I want to use Reactive Extensions for this task.
The consumer side of this is very straightforward; I have my consumer class implementing IObserver<Payload> and all seems well. The problem comes on the producer class.
Implementing IObservable<Payload> directly (that is, putting my own implementation for IDisposable Subscribe(IObserver<Payload> ) is, according to the documentation, not recommended. It suggests instead composing with the Observable.Create() set of functions. Since my class will run for a long time, I've tried creating an Observable with var myObservable = Observable.Never(), and then, when I have new Payloads available, calling myObservable.Publish(payloadData). When I do this, though, I don't seem to hit the OnNext implementation in my consumer.
I think, as a work-around, I can create an event in my class, and then create the Observable using the FromEvent function, but this seems like an overly complicated approach (i.e., it seems weird that the new hotness of Observables 'requires' events to work). Is there a simple approach I'm overlooking here? What's the 'standard' way to create your own Observable sources?
Create a new Subject<Payload> and call it's OnNext method to send an event. You can Subscribe to the subject with your observer.
The use of Subjects is often debated. For a thorough discussion on the use of Subjects (which links to a primer), see here - but in summary, this use case sounds valid (i.e. it probably meets the local + hot criteria).
As an aside, overloads of Subscribe accepting delegates may remove the need for you to provide an implemention of IObserver<T>.
Observable.Never() doesn't "send" notifications, you should use Observable.Return(yourValue)
If you need a guide with concrete examples i recommend reading Intro to Rx
Unless I come across a better way of doing it, what I've settled on for now is the use of a BlockingCollection.
var _itemsToSend = new BlockingCollection<Payload>();
IObservable<MessageQueuePayload> _deliverer =
_itemsToSend.GetConsumingEnumerable().ToObservable(Scheduler.Default);

I need some explain on Rx behavior

When I use Reactive Extensions (Rx) with linq filter what happen under the hood?
Is this,
var move = Observable.FromEventPattern<MouseEventArgs>(frm, "MouseMove");
IObservable<System.Drawing.Point> points = from evt in move
select evt.EventArgs.Location;
var overfirstbisector = from pos in points
where pos.X == pos.Y
select pos;
var movesub = overfirstbisector.Subscribe(pos => Console.WriteLine("mouse at " + pos));
more efficient from this?
private void MouseMove(object sender, EventArgs args)
{
if (args.Location.X == args.LocationY)
Console.WriteLine("mouse at " + args.Location);
}
I dont talk about the filtering logic itself but about the events behavior of the methods.
In Rx do the event raised exactly the same way of the regular event but with warapper or there is somthing special under the hood?
In this case, there's no algorithmic performance benefit for using the Rx query over the typical event handler - in fact, your Rx query may actually be marginally slower than the typical event handler. "Under the hood" the Rx query is basically doing the same thing as the typical event handler, but in a cleaner way.
The Rx query is not more efficient than the directly subscribing the events. Under the hood, the Rx query is still subscribing to the events and adding a bit of logic (e.g. for the schedulers), so I would say you are trading a bit of performance for increased readability, flexibility (since you can quickly change and adapt the query) and testability (since the Rx query can be much more easily unit-tested).
There is nothing "special" about Rx. Rx is just a library, not a language feature. If you wanted to, you could have built Rx yourself in a normal old C# project, it just happened that the smart people at Microsoft thought of it first. The code is open source now so you can just download it and see how it all works (admittedly it got a lot more complex in v2)
In your example, the Rx code will need to do the following:
Reflectively look for an event called "MouseMove" on the frm object
Create an observable sequence (IObservable<MouseEventArgs>) from the event
Ensure the safe semantics of the implicit IObservable contract e.g. that values are sequential, the subscriptions are thread safe etc..
Do the condition check
Subscribe to the sequence (safely)
Print to the console when a value is pushed.
In contrast, the non-rx code does the following:
Recieves a virtual call from a base class
does the condition check
Prints the value to the console.
So no reflection & no safety checks, but the same result. In practice the performance will be very fast for both so you are unlikely to see any performance difference.
With regards to Unit testing, I think any argument for or against is nonsense. We are talking about a MouseMove event, how are you going to unit test that? Putting all that Rx in your code base doesn't appear to pay for itself in my opinion (slower, more code, another framework for a dev to understand, etc...)

Categories