Is there a `when()` statement or some equivalent in C#? - 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.

Related

Reactive Extensions unfold / scan approach for nested hierarchy

I'm currently building a wizard system for an application, and we're using ReactiveUI and as a result Rx.
Each step in the wizard implements IWizardStep<T> where T is just the data type that the wizard ultimately produces.
Each step has the capability of surfacing which step should be available for the user to move to next, so as to enable branching based on data entry.
The step can be thought of having a similar structure to:
public interface IWizardStep<T>
{
IObservable<IStepChoice<T>> NextStepChoice {get;}
}
With IStepChoice<T> simply being:
public interface IStepChoice<T>
{
IWizardStep<T> Step {get;}
string Reason {get;}
}
In order to calculate the current path from the start to the end, for display to the user, I need to be able to go from the starting step, and walk along the NextStepChoice chain recursively until it hits a null (it's valid behaviour for the NextStepChoice observable to emit a null to indicate the end of the wizard).
I've taken a look at Observable.Scan but can't for the life of me work out how to get this working properly recursively.
I've also taken a look at Observable.Generate which looks promising, as this is a classic unfold-esque problem; the only issue is that Generate takes a function to determine when to break the loop, but I need to evaluate the inner observable to work this out.
Observable.Generate(
new WizardStepChoice<T>(start, null),
choice => choice != null,
choice => choice.ChosenStep.NextStepChoice,
choice => choice);
This would be ideal, and produce the output I'm after, but the NextStepChoice selector there obviously doesn't compile because it's an IObservable<IWizardStepChoice<T>> rather than an IWizardStepChoice<T>.
I've looked at using Aggregate and Scan but as these are more fold-driven operations, and I've only got the starting element, it's an unfold I'm looking for ala Generate, but I need it to be able to evaluate the nested observable.
Would Observable.Create perhaps be something I could utilise? I've tried it and come up with:
Path = CurrentStep.Select(_ => Observable.Create<IWizardStep<T>>(async observer =>
{
IWizardStepChoice<T> next = new WizardStepChoice<T>(start, null);
observer.OnNext(next.ChosenStep);
while (next != null)
{
next = await next.ChosenStep.NextStepChoice;
observer.OnNext(next.ChosenStep);
}
observer.OnCompleted();
return Disposable.Empty;
}).Aggregate(new List<IWizardStep<T>>(),
(l, s) =>
{
l.Add(s);
return l;
})).Switch().Publish().RefCount();
Which has all the right signature I want IWizardStep<T>->IReadOnlyList<IWizardStep<T>>, so at first glance it looks right, but it doesn't work; it fires, and I can step through, but it hangs once it hits the await and doesn't come back.
I've got a feeling I'm close, and this is a scheduling issue, so my question really is this:
What is the best approach to solve this, am I close?
If this is right, why is there an issue with the await, and how might I solve it?
Update
After a little bit of tinkering I noticed that the await was likely hanging as that observable hadn't yet (and wasn't going to) emit a value (duh), which I've now resolved by initialising each step with a value at the beginning of the wizard.
I've even sanity-checked this by adding a property to IWizardStep<T> - IWizardStepChoice<T> LatestStepChoice {get;} which is just hooked up with:
NextStepChoice.Subscribe(c => _latestStepChoice = c);
This is done on the step class itself, and I can confirm it's working just fine.
Yet still the await hangs, so I tried:
Making it Replay(1) so the await calling .Subscribe() would get the value - this didn't work
Making it Repeat() so even if something is subscribed it'll see the new value - this just made the whole thing hang.
Clearly I'm missing something here, I want it so that when the await queries the observable, it will be given the latest value seen, which is what I thought Replay(1) would achieve; I've also tried PublishLast() but then future updates don't get honoured because of the AsyncSubject<T> behaviour.
For now I've switched to using the self-subscribed property, but it's not ideal, I'd rather not have to break out of querying the observables if I can help it, it feels "hacky".
A recursive walk can transform the tree of observables into a single observable:
static IObservable<IWizardStep<T>> Walk<T>(IWizardStep<T> step)
{
if (step?.NextStepChoice == null)
return Observable.Return(step);
return step.NextStepChoice.SelectMany(choice => Walk(choice.Step)).StartWith(step);
}
Usage:
var steps = await Walk(step).ToArray();

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());
//....

What better ways are there to instantiate a class specified at runtime, and call a method on that instance?

I have a command line application that has to be able to perform one of a number of discrete tasks, given a verb as a command line argument. Each task is handled by a class, each of which implements an interface containing a method Execute(). I'm trying to do this without using if or switch statements. So far, what I have is this:
var taskTypeName = $"MyApp.Tasks.{invokedVerb}Task";
var taskType = Type.GetType(taskTypeName, false);
var task = Activator.CreateInstance(taskType) as IMaintenanceTask;
task.Execute();
task is of type IMaintenanceTask, which is fundamentally what I'm trying to achieve. I'd prefer to avoid using dynamic - my understanding is that if it's only used once, like here, I won't see any of the benefits of caching, making it just reflection in fewer keystrokes.
Is this approach (or something along the same lines) likely to noticeably affect performance? I know it definitely increases the chance of runtime exceptions/bugs, but that's partly mitigated by the fact that this application is only going to be run via scripts; it will only deal with predictable input - also this will be the only place in the code that behaves dynamically. Is what I'm trying to achieve sensible? Or would it be better to just do this the boring normal way, via just switching on the input and constructing each type of task via a normal, compile-time constructor, and calling .Execute() on that.
As it is just one time call, you can go with your solution. Just add a few conditions to avoid exception chances.
var taskTypeName = $"MyApp.Tasks.{invokedVerb}Task";
var taskType = Type.GetType(taskTypeName, false);
if (taskType != null && typeof(IMaintenanceTask).IsAssignableFrom(taskType))
{
var task = Activator.CreateInstance(taskType) as IMaintenanceTask;
task.Execute();
}
Don't worry about the performance of a dispatch mechanism, unless it is in a tight loop. Switching a single direct method call to a single call through dynamic, a single call through reflection, a single call through emit API, or a single call through compiled LINQ expression will not make a detectable difference in execution time of your application. The time it takes operating system to start up your application is several orders of magnitude higher than the time it takes your application to decide what method to call, so your solution is as good as a switch, except it is a lot shorter (which is a good thing).

.NET TPL Declaration issues

I am having a difficult time understanding the TPL and I cannot find many clear articles on it. Most seem to use simplistic examples with lambda expressions.
I have a C# function
int[] PlayGames(int[][] boardToSearch, int numGamesToPlay) {…}
I want to make this threadable using the .NET 4.6 TPL in C#. I want to launch up to 8 of these functions at once, wait until they all finish, capture the results and move on.
I can’t seem to get the types right and it’s not working as expected.
Here’s what I’ve got so far:
Task<int[]> PlayGames(int[][] boardToSearch, int numGamesToPlay) {…code that takes a long time…}
private int FindBestMove(int[][] boardToSearch, int numGamesToPlay)
{
…
var taskList = new List<Task>();
taskList.Add(Task.Factory.StartNew(() => { return PlayGames(boardToSearch, numGamesToPlay); }));
taskList.Add(Task.Factory.StartNew(() => { return PlayGames(boardToSearch, numGamesToPlay); }));
// Tests
Task a = taskList.First();
var a1 = a.Result; // NOT ALLOWED!? Viewable in debugger, cannot access it.
var b = Task.FromResult(a);
var b1 = b.Result; // Works but cannot access child member Result. Debugger sees it, I can’t!?
Task.WaitAll(taskList.ToArray());
…
}
Here are my questions
How do I remove the lambda expression () => { return PlayGames(boardToSearch, numGamesToPlay); }? I want to use Func() somehow but I cannot for the life of me figure out how to say “Task.Factory.StartNew<int[]>(Func(PlayGames(boardToSearch, numGamesToPlay)))”.
Why do I need to use StartNew()? When I do taskList.Add(PlayGames(int[][] boardToSearch, int numGamesToPlay)), it does it synchronously!? What is the correct syntax to add a task to a list in this manner? Do I need to declare a Func of some sorts that I pass to something like new Task(Func(PlayGames))?
When you look at variable a after executing the line Task a = taskList.First(), it clearly shows a member called Result in the debug pane. And if I expand that result it contains the right data! But if I click on add watch to the Result member, I get an error! And if I do a.Result, the compiler gives me the same error!?? So the debugger says it’s there but I cannot view it on its own!?? I can browse it from the a object but not directly. I included a screenshot of this so others could see.
What is the cleanest way to do this with .NET 4.6 while staying away from lambda expressions. I want to see all the types and the declarations.
Attached is a screenshot of my debugger so you can see what I mean with .Result
Let's start from the top:
1] Func it's just a delegate that's the part of .net framework libraries.
So, when you pass () => { return PlayGames(boardToSearch, numGamesToPlay); } it means you just create an anonymous method which has a type of Func<int[]>. If you assign this lambda expression to some variable then you can check this type.
If you don't want to use lambda you can write a common method and put it inside the task: Task.Factory.StartNew(YourMethodWhichReturnsIntArray).
2] When you call StartNew() method it just creates a new Task and starts execute this. That's it.
taskList.Add(PlayGames(int[][] boardToSearch, int numGamesToPlay)) - this just put the Task into the taskList. If inside your PlayGames method this Task wasn't started then you will need to do it sometime after. Synchronous or not - adding Task to list is synchronous operation, but executing still will be asynchronous. Any syntax might be correct or not - it depends on complexity and realization. Instead of Task.Factory.StartNew(), you can you a just Task.Run() method. It does the same, but in a bit shorten manner. And it's not necessary to declare a func before passing to the Task.
3] I believe is that's because the debugger has an ability to wait for the results from a parallel thread/task, but watcher doesn't. That's why you get an error.
So, I would say do not try to add watcher for the parallel threads results (just to skip the possible errors).
4] What is the cleanest way to do this with .NET 4.6 while staying away from lambda expressions. I want to see all the types and the declarations.
As I said above, it's not necessary to declare the lambda. You can create a method with the correspond definition. But here you will face some difficulties with passing the parameters to this method (but they still could be solved). So, lambda - is the easiest way to pass function to the Task, because it can easily capture you parameters from the scope where these lambda's have been created.
What is the cleanest way - again, it depends. Each of us has his own cleanest way to run new tasks. So, I think that (see below):
// your function
int[] PlayGames(int[][] boardToSearch, int numGamesToPlay) {…}
private int YouMethodToRun8Tasks(int[][] boardToSearch, int numGamesToPlay)
{
...
var taskList = new List<Task<int[]>>();
// create and run 8 tasks
for(var i = 0; i < 8; i++)
{
// it will capture the parameters and use them in all 8 tasks
taskList.Add(Task.Run<int[]>(() => PlayGames(boardToSearch, numGamesToPlay));
}
// do something else
...
// wait for all tasks
Task.WaitAll(taskList.ToArray());
// do something else
}
might be named as cleanest way in some cases.
I hope it will help you.

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

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.

Categories