I'm new to Rx and have this code snippet for a try.
Observable.Never<string>().Subscribe(Console.Write);
Observable.Empty<string>().Subscribe(Console.Write);
I expected that Never<string>() will behave like Console.ReadKey which will not end, but as I run these 2 lines, they end immediately, so [Never] behaves like [Empty] to me.
What is the correct understanding of [Never] and is there a good sample usage for it?
Both the Observable.Never() and Observable.Empty() observable will not emit any values. However, the observable built with Observable.Never() will not complete and instead stays "open/active". It might be a difference at the location where you consume these observable if the observable completes (Empty()) or not (Never()), but this depends on your actual use-case.
Having observables which doesn't emit any values might sound useless, but maybe you are at a location where you have to provide an observable (instead of using null). So you can write something like this:
public override IObservable<string> NameChanged => Observable.Never<string>();
So I don't have a ton of experience with Rx, but I believe all Subscribe is doing is registering what to do when the observable emits. If your observable never emits (ie Empty or Never) then the method is never called. The application is not waiting for the subscription itself to end. If you wanted to wait forever you would use something like
Observable.Never<string>().Wait();
This ties back into the reason you should not use async operation in Subscribe. Take the following code
static void Main(string[] args)
{
Observable.Range(1, 5).Subscribe(async x => await DoTheThing(x));
Console.WriteLine("done");
}
static async Task DoTheThing(int x)
{
await Task.Delay(TimeSpan.FromSeconds(x));
Console.WriteLine(x);
}
When run the application will immediately write "done" and exit after pushing the values into the observable because it is unaware of the subscriber in the context of whether it has completed its handling or not. Hopefully I made that clear, and if someone with more Rx knowledge wants to step in to help if needed that'd be good.
This link gives you the difference between empty,never ,and throw:
http://reactivex.io/documentation/operators/empty-never-throw.html
And this is one usage of Never:
https://rxjs-dev.firebaseapp.com/api/index/const/NEVER
Related
I have an I/O-bound task implemented with an async-await function.
At some point in this function, I receive some information which allows me to start a concurrent task, which is also I/O-bound (and so it is also implemented with an async-await function). My original task is not bound by this new task - I just need to set it going in the background.
If I do the following, I get warned that I'm not awaiting the call. I don't want to await the call! I want it to happen in the background!
async Task AnotherAsyncThing()
{
// ...
}
async Task SomeAsyncThing()
{
// ...
// run concurrently - warning raised here
Task.Run(async () => await AnotherAsyncThing());
// ...
}
Am I missing something horribly obvious here? It feels like I am!
You can do something like this:
_ = AnotherAsyncThing()
This is the discards feature added in C# 7.0 and is a way of communicating the fact you're not interested in the return value to the compiler.
Yes and no :)
so often bugs occur when people forget to wait for tasks and it is considered a risk in APIs for instance to keep spinning up non awaited tasks because you can sometimes do so rapidly with bad performing client code and if that can steal many resources ... we'll i'm sure You can imagine.
But to signify that You know what You're doing and assume full responsibility, You can use the TPL like this and get rid of the warnings
_ = Task.Run(
() => _ = AnotherAsyncThing()
);
But each time this code is passed it will continue immediately and start something which will also continue to run. So Say your API gets a post, which accidentally happens every 10th millisecond instead of every 10th second as intended ... there is a danger in making the use of these things a standard.
It is a tool for a specific purpose, not the new white for walls, but yea You may have missed that we now should tell by using the nevermind underscore, that we know what we're doing this time and the compiler should back out from helping.
I am new to C# async programming and need to see if which of the following is a preferred way to deal with Task object.
I have a class that does this:
var value = this.SomeFunction(...);
var innerValue = await Task.FromResult(value.Result);
Somefunction looks like below.
protected async Task<JObject> Somefunction(..)
{
..
returns JBoject
..
}
This works fine as expected. Now, I have a suggestion that I shouldn't be using Task.FromResult with async functions.
Instead, I should be using something like:
var innerValue = await value; //..this works fine too
But I am not really sure why the 1st one isn't a good practice to get the same thing done.
Any leads would be helpful.
Thanks
Let's go through what you're doing and say precisely why it is wrong.
var value = this.SomeFunction(...);
First off: use var when the type is either clear or unimportant. The type is not clear here and it is important.
Second: Name functions that are asynchronous with an Async suffix.
Let's fix up your example. It's still wrong, but now it is more clear:
Task<Toast> toastTask = this.StartToasterAsync();
Toast toast = await Task.FromResult(toastTask.Result);
This workflow is completely wrong. Let's translate it into English. Here's my to-do list for today:
Put some bread in the toaster.
While the bread is toasting I could be doing other work, but instead, stare at the toaster doing nothing else until it is done.
Get the toast from the toaster, and start a new to-do list.
The new to-do list is: Obtain the piece of toast that I am now holding.
Execute that to-do list. While I'm waiting for the to-do list to complete, go do other work, but the to-do list is always already complete because the job is to obtain a result that I have already obtained. So don't do other work. Just check that yes, I am in fact holding the piece of toast I just wrote a to-do list about.
Now I have a piece of toast.
This workflow is an insane way to make toast. It works -- you end up with a piece of toast at the end -- but no sensible person would do this, and you should not write the equivalent computer program:
It is an "asynchronous" workflow where every possible asynchronous advantage has been removed.
The first step -- waiting for the toaster to pop -- has been synchronously waited.
The second step -- asynchronously wait for a task that has already completed -- is never asynchronous!
Never never never write asynchronous code this way.
The right workflow for making a piece of toast is:
Put the bread in the toaster and start it toasting.
Do other work until the toast pops.
Fetch the toast.
And as we'd expect, the correct way to write your program is much simpler:
Task<Toast> toastTask = this.StartToasterAsync(...);
Toast toast = await toastTask;
Or even better:
Toast toast = await this.StartToasterAsync(...);
You're new to this and you have not internalized the meanings of the various operations on asynchronous workflows. The operations in your little program are:
.Result means stop being asynchronous and do nothing until the result is available. Note that this can cause deadlocks. You are stopping a thread until the result is available; what if you are stopping the thread that was going to produce the result in the future? Imagine for instance that we did a to-do list of "(1) Order a box of chocolates from the internet. (2) Do nothing until the chocolates arrive. (3) Get the chocolates out of the mailbox." That workflow does not complete because there is a synchronous wait for a result that requires you to do work in the future.
await means this workflow cannot continue until the result is available so asynchronously wait for it. Go off and find other work to do, and when the result is available, we'll start again here.
Note that both of them mean the same thing, in that both are points in a workflow where the workflow does not proceed until the result is available. But they are completely different in that Result is a synchronous wait, and await is an asynchronous wait. Make sure you understand this. It is the most fundamental point that you must understand.
And finally
FromResult means someone needs a task, but I already have the result of that task, so make a task that is already complete. When it is awaited or when Result is called on it, either way, it returns the result immediately.
It is unusual to call FromResult. If you are in an asynchronous workflow, normally you would just return result; to signal that a task was complete.
The problem in the first version is not the use of Task.FromResult, which, from the documentation:
Creates a Task<TResult> that's completed successfully with the specified result
The problem is the call value.Result which performs a synchronous wait. So, you are essentially asynchronously waiting for a synchronous result.
Notice that the first version is a bad wrapper (because of the code that must be generated for the await call) around this:
var value = this.SomeFunction(...);
var innerValue = value.Result;
To sum up, just use this:
var innerValue = await value;
Or, if there's no code to run between value and innerValue, you can ignore the assignment of value altogether
var innerValue = await this.SomeFunction(...);
I have been putting off using reactive extensions for so long, and I thought this would be a good use. Quite simply, I have a method that can be called for various reasons on various code paths
private async Task GetProductAsync(string blah) {...}
I need to be able to throttle this method. That's to say, I want to stop the flow of calls until no more calls are made (for a specified period of time). Or more clearly, if 10 calls to this method happen within a certain time period, i want to limit (throttle) it to only 1 call (after a period) when the last call was made.
I can see an example using a method with IEnumerable, this kind of makes sense
static IEnumerable<int> GenerateAlternatingFastAndSlowEvents()
{ ... }
...
var observable = GenerateAlternatingFastAndSlowEvents().ToObservable().Timestamp();
var throttled = observable.Throttle(TimeSpan.FromMilliseconds(750));
using (throttled.Subscribe(x => Console.WriteLine("{0}: {1}", x.Value, x.Timestamp)))
{
Console.WriteLine("Press any key to unsubscribe");
Console.ReadKey();
}
Console.WriteLine("Press any key to exit");
Console.ReadKey();
However, (and this has always been my major issue with Rx, forever), how do I create an Observable from a simple async method.
Update
I have managed to find an alternative approach using ReactiveProperty
Barcode = new ReactiveProperty<string>();
Barcode.Select(text => Observable.FromAsync(async () => await GetProductAsync(text)))
.Throttle(TimeSpan.FromMilliseconds(1000))
.Switch()
.ToReactiveProperty();
The premise is I catch it at the text property Barcode, however it has its own drawbacks, as ReactiveProperty takes care of notification, and I cant silently update the backing field as its already managed.
To summarise, how can I convert an async method call to Observable, so I can user the Throttle method?
Unrelated to your question, but probably helpful: Rx's Throttle operator is really a debounce operator. The closest thing to a throttling operator is Sample. Here's the difference (assuming you want to throttle or debounce to one item / 3 seconds):
items : --1-23----4-56-7----8----9-
throttle: --1--3-----4--6--7--8-----9
debounce: --1-------4--6------8----9-
Sample/throttle will bunch items that arrive in the sensitive time and emit the last one on the next sampling tick. Debounce throws away items that arrive in the sensitive time, then re-starts the clock: The only way for an item to emit is if it was preceded by Time-Range of silence.
RX.Net's Throttle operator does what debounce above depicts. Sample does what throttle above depicts.
If you want something different, describe how you want to throttle.
There are two key ways of converting a Task to an Observable, with an important difference between them.
Observable.FromAsync(()=>GetProductAsync("test"));
and
GetProductAsync("test").ToObservable();
The first will not start the Task until you subscribe to it.
The second will create (and start) the task and the result will either immediately or sometime later appear in the observable, depending on how fast the Task is.
Looking at your question in general though, it seems that you want to stop the flow of calls. You do not want to throttle the flow of results, which would result in unnecessary computation and loss.
If this is your aim, your GetProductAsync could be seen as an observer of call events, and the GetProductAsync should throttle those calls. One way of achieving that would be to declare a
public event Action<string> GetProduct;
and use
var callStream= Observable.FromEvent<string>(
handler => GetProduct+= handler ,
handler => GetProduct-= handler);
The problem then becomes how to return the result and what should happen when your 'caller's' call is throttled out and discarded.
One approach there could be to declare a type "GetProductCall" which would have the input string and output result as properties.
You could then have a setup like:
var callStream= Observable.FromEvent<GetProductCall>(
handler => GetProduct+= handler ,
handler => GetProduct-= handler)
.Throttle(...)
.Select(r=>async r.Result= await GetProductCall(r.Input).ToObservable().FirstAsync());
(code not tested, just illustrative)
Another approach might include the Merge(N) overload that limits the max number of concurrent observables.
Is there an example out there showing me how the Observable.Count<TSource> Method actually works? The examples I come up with appear to return a count wrapped in an observable instead of the expected count.
For example, I expect 1 to be returned from this:
System.Diagnostics.Debug.WriteLine((Observable.Return<string>("Hello world!")).Count());
Will 1 be returned in the future (because, after all, it is an asynchronous sequence)? Or am I missing a few things fundamental? As of this writing, I actually assume that .Count() will return the results of T and grow over time as long a results are pushed out. Really? Yes.
The aggregate operators in Rx work a bit differently than in LINQ - they do not immediately return a value, they return a future result (i.e. we can only know what the final Count is once the Observable completes).
So if you write:
Observable.Return("foo").Count().Subscribe(x => Console.WriteLine(x));
>>> 1
because, after all, it is an asynchronous sequence
This actually isn't exactly true. Here, everything will be run immediately, as soon as somebody calls Subscribe. There is nothing asynchronous about this code above, there are no extra threads, everything happens on the Subscribe.
I think that using an observable that returns immediately and also using the async/await syntax as rasx did in the comments is confusing matters rather too much.
Let's create a stream with 5 elements that come back one every second and then complete:
private IObservable<long> StreamWith5Elements()
{
return Observable.Interval(TimeSpan.FromSeconds(1))
.Take(5);
}
We can call it using async/await magic as in this LINQPad friendly example:
void Main()
{
CountExampleAsync().Wait();
}
private async Task CountExampleAsync()
{
int result = await StreamWith5Elements().Count();
Console.WriteLine(result);
}
But it's misleading what's going on here - Count() returns an IObservable<int>, but Rx is super-friendly with await and converts that result stream into a Task<int> - and the await then hands back that task's int result.
When you use await against an IObservable<T>, you are implicitly saying that you expect that observable to call OnNext() with a single result and then call OnComplete(). What actually happens is that you will get a Task<T> that returns the last value sent before the stream terminated. (Similar to how AsyncSubject<T> behaves).
This is useful because it means any stream can be mapped to a Task, but it does require some careful thought.
Now, the above example is equivalent to the following more traditional Rx:
void Main()
{
PlainRxCountExample();
}
private void PlainRxCountExample()
{
IObservable<int> countResult = StreamWith5Elements().Count();
countResult.Subscribe(count => Console.WriteLine(count));
/* block until completed for the sake of the example */
countResult.Wait();
}
Here you can see that Count() is indeed returning a stream of int - to provide an asynchronous count. It will return only when the source stream completes.
In the early days of Rx, Count() was in fact synchronous.
However, that's not a terribly useful state of affairs since it "Exits the Monad" - i.e. brings you out of IObservable<T> and prevents you from further composition with Rx operators.
Once you start "thinking in streams", the asynchronous nature of Count() is quite intuitive really, since of course you can only provide a count of a stream when it's finished - and why hang around for that?? :)
I rewrote some old async code of mine that makes that makes SOAP calls. The fetch() method would go out, get the result from the SOAP interface, and then add it to a DataTable that is bound to my WPF view. The new code uses Reactive Extensions to get a list of strings and creates an IObservable from the list. I thought it would return the results asynchronously, but the entire UI locks up until the entire result set is ready. I'm new to Reactive Extensions so I'm hoping I'm just missing something simple.
The Code:
(from click event)
private void fetchSoapRows()
{
var strings = (txtInput.Text.Split('*')).ToObservable();
strings.Subscribe(s=> SoapQueryEngine.Fetch(s));
}
Also, does anyone know how I could write a test to make certain this method doesn't block the application in the future?
There are two parts to an observable query, the Query itself and the Subscription.
Your Query is an IEnumerable<string> producing values as fast as the computer can do it.
Your Subscription is
SoapQueryEngine.Fetch(s);
This runs Fetch for each string produced by the Query in the Subscriber thread which tends to be the thread where you're setting up your Subscription (although it isn't necessarily).
The issue has to do with the intention and design of Rx. It's intended that the Query is the long-running process and the Subscription is a short method that deals with the results. If you want to run a long running function as an Rx Observable your best option is to use Observable.ToAsync.
You should also take a look at this question to see a similar problem which shows more of what's going on in the background.
There is nothing inherently concurrent about Rx. If you want to make your calls to Fetch you will need to change SoapQueryEngine so that it is async or call it on another thread and then bring the results back to the UI thread.
Try this way. Instead of subscribing to the event text changed event, create an observable on the event and observe it on the thread pool:
Observable.FromEventPattern(<subscribe event>, <unsubscribe event>)
.ObserveOn(ThreadPoolScheduler.Instance)
.SelectMany(s => s.Split('*'))
.Subscribe(s=> SoapQueryEngine.Fetch(s));