Take the following class and suppose Calculate is a very calculation intensive function.
class Algorithm
{
FinalResultObject Calculate()
{
longPartialCalculation();
//signal to caller that that part is ready of type MidResult1
morePartialCalculation();
//signal more is ready, different type of MidResult2
moreWork();
return finalResult;
}
}
Now suppose, intermediate results need to be shown to the user whenever they're ready.
The options I see are:
use separate events to signal
use constructor injection to inject the a handler class whose methods are being called
use RX observables
I'm new to RX but I'm liking the idea that I can easily do the event handling on the UI thread. I'm wondering though if this is overkill and not as intended since it's not really a whole stream of data but just one result for each observable. On the other hand though just as with events subscription and unsubscription seems to be so cumbersome.
Any hints?
The Rx way of tackling this problem is to define a cold observable as follows:
IObservable<Result> Calculate(IScheduler scheduler)
{
return Observable.Create<Result>(observer =>
scheduler.Schedule(() =>
{
observer.OnNext(longPartialCalculation());
observer.OnNext(morePartialCalculation());
observer.OnNext(moreWork());
observer.OnCompleted();
}));
}
// Depending upon your needs, you could use inheritance as follows:
public abstract class Result { ... }
public class MidResult1 : Result { ... }
public class MidResult2 : Result { ... }
public class FinalResultObject : Result { ... }
You could also define an overload that specifies a default scheduler, such as ThreadPoolScheduler if you want to introduce concurrency or CurrentThreadScheduler if you don't.
To use the observable that is returned by this method, simply call Subscribe with an observer. You can provide an OnNext handler to inspect each Result object as it arrives and an OnCompleted handler to handle completion. You can also provide an OnError handler to handle an Exception, if you must.
(Edit: Note that OnError isn't called by my example though.)
If you want to ensure that all of these handlers execute on the UI thread, and you've passed in a concurrency-introducing scheduler such as ThreadPoolScheduler to the Calculate method, then you can also apply the ObserveOn operator (or ObserveOnDispatcher on XAML-based platforms) to marshal all notifications to the UI thread for observation.
algo.Calculate(ThreadPoolScheduler.Instance)
.ObserveOnDispatcher()
.Subscribe(OnNextResult, OnCompleted);
Note that one of the primary benefits of Rx is the ability to query; e.g., a simple filter:
algo.Calculate(ThreadPoolScheduler.Instance)
.Where(result => result.HasRequiredState)
.ObserveOnDispatcher()
.Subscribe(result => handle(result.RequiredState));
You can use .Net's Progress<T>. You create an instance, passing a handler or registering to its event and report through it throughout you long-running process:
var progress = new Progress<string>(value => Console.WriteLine(value));
Calculate(progress);
FinalResultObject Calculate(IProgress<string> progress)
{
longPartialCalculation();
progress.Report("MidResult1");
morePartialCalculation();
progress.Report("MidResult2");
moreWork();
return finalResult;
}
In this case, the report is writing a string to console, but you can of course use for any type you want.
Progress<T> also captures the current SynchronizationContext on creation so you could create it in the UI thread, pass it to a non-UI thread without any synchronization issues.
Related
I have a helper class that saves text messages to the local file system. This method returns a Task object, and is asynchronous by definition.
I want to be able to observe when this method gets called, so I can continuously monitor the size and length of the buffer and make a decision based on that.
I am trying to implement this using the Reactive Extension for .NET. However, I can't come up with a design that allows me to continuously listen to messages being added to the buffer. Below is my current implementation:
public IObservable<Unit> Receive(InternalMessage message)
{
var observable = FileBuffer.BufferMessage(message.MessageId.ToString(), message, DateTime.UtcNow).ToObservable(); //This returns a Task, which I convert into an Observable
return observable;
}
Here is how I subscribe to the observable:
IObservable<Unit> receiverObservable = batchHandler.Receive(message);
receiverObservable.Subscribe(
x => Console.WriteLine("On next"),
ex => //TODO,
() => // Completed);
I want the subscriber to be called every time the method Receive is called. However, AFAIK, once this method is called, the observable completes and the sequence is terminated, so future calls to Receive won't be listened to.
Can someone recommend a way to use the Rx.Net libraries to implement this observable pattern that I am looking for, that is, how to keep the sequence open and feed it with results for async methods?
Receive as you've coded it, returns IObservable<Unit>, representing the completion of a single task. You want to subscribe to something that returns IObservable<IObservable<Unit>> representing a stream of task-completions.
There are a number of ways to do this, the best of which probably depends on how your class is set up and how you're calling it.
Here's the laziest one:
You declare a class-level variable subject that represents a stream of your calls:
Subject<IObservable<Unit>> subject = new Subject<IObservable<Unit>>();
subject.Merge().Subscribe(
x => Console.WriteLine("On next"),
ex => { }, //TODO
() => { } // Completed
);
Then when you have a new call, you just add it to the subject.
IObservable<Unit> receiverObservable = batchHandler.Receive(message);
subject.OnNext(receiverObservable);
The reason this is really lazy is that Rx is functional at its core, which tends to look down on mutable-state variables. Subjects are basically mutable state.
The better way to do it is to figure out when/why you're calling Receive, and structure that as an observable. Once that's done, you can work off of that:
IObservable<Unit> sourceReasonsToCallReceive; // Most likely sourced from event
sourceReasonsToCallReceive.SelectMany(_ => batchHandler.Receive(message))
.SubScribe(
x => Console.WriteLine("On next"),
ex => { }, //TODO
() => { } // Completed
);
Hope that helps.
I am fairly new to reactive UI. I am using it in my app extensively for async programming etc.
I have a question. I have a method in my ViewModel which is async and which "awaits" for a task to complete. On completion of this task, I would like to notify my view (a UserControl) so it can dynamically add some more content/UserControls, to say, a DockPanel.
What is the best way of doing this using ReactiveUI or RX? I could use C# event mechanism , etc. but I want to continue down the RX path. I set a boolena property in my VM when the async method has "completed" (i.e. returned from await).
I then want to observe for this boolean property (defined in my VM) in my "View"..so I can attach a handler in my "View" which will dynamically create some UserControls, e.g.
this.viewModel.ObservableForProperty(x => x.DataLoaded)
.Subscribe(async _ => await this.MyViewHandler());
// this does not compile as the delegate is not IObserver type in my view it says
Any guidance will be much appreciated, many thanks.
You've mostly got the right idea, just need some work on the syntax:
this.WhenAnyValue(x => x.ViewModel.DataLoaded)
.Where(x => x == true)
.Subscribe(_ => MyViewHandler());
The problem with your example code is that as the compiler says, you are not passing a valid IObserver implementation to the Subscribe method. You are actually passing an Func<boolean, Task> where it is expecting an Action<boolean> implementing the IObserver.OnNext.
I haven't tried ReactiveUI, but I think you can accomplish but you intend with either Task Continuation or with the IObserver.OnCompleted. A couple ideas are:
Using Task Continuation you'd launch another task once the one you mentioned has finished. You can do this by appending a .ContinueWith call to your task. Keep in mind that code from the continuation task modifying the UI must be dispatched to the UI thread from the continuation task (either using the Dispatcher or by passing the proper TaskScheduler to ContinueWith).
With RX, you could create a sequence for your task with the proper Observable.Create factory method or simply using the Task.ToObservable extension methods, then subscribe to it and do whatever you want on the OnCompleted handler.
BACKGROUND:
I have a class with multiple operations that take more than a couple of seconds to finish. In the meantime I want to update the UI. So normally the BackgroundWorker is the way to go. But for some reason the BackGroundWorker doesn't always work the way I want (example: when I try to use a WebBrowser with events and call the ReportProgress event the BackgroundWorker seemingly crashes).
So I avoid all of this by seperating the Ui from the main thread.
This pseudocode explains it better:
public Ui ui;
main
{
Thread threadUi = new Thread(initiateUi);
//Initiate and start Thread
//Everything I will do from here on will not have any consequences
//on my ui.
//
//Object Ui can still be publicly accessed, making it possible to
//update the user interface.
}
Now when I have an instance of class Bar I would make it accessible for the UI like this:
public Bar bar1;
public Bar bar2;
main
{
//
//other stuff here
//
Thread threadBar1 = //New Thread where I call the Bar initializer function
//and pass bar1 as parameter.
Thread threadBar2 = //idem dito, except with bar2 as parameter
//
//other stuff here
//
}
With this design I can call bar1 and bar2 from my user-interface with the following function:
Program.bar1.someFunction();
PROBLEM:
Now let's say I have a class called FooHandler. This class has a function that searches for all instances of Foo in a certain FooDepository and other functions to manipulate a Foo-object. This is a static class, because in my case, it doesn't need to have multiple instances.
But if I were to call a function from FooHandler, the function runs in my UI-thread, because that is the calling thread (I am not really sure but I couldn't find any documentation about this subject). So there is a good chance I am about to face the problem I started with.
QUESTION:
Is it possible to access the function of a static class without using processing power from the calling thread?
First of all: method scope (where it is defined) has NOTHING to do with program flow. Where method is defined (FooHandler, BarProvider or ThreadX) does not affect where it is called. Actually method is always called in caller's thread.
Because you didn't mention any models, views nor view models and in title says "c#" I'm assuming you talking about WinForms.
In WinForms UI controls needs to be called (updated) from the thread which was used to create them (usually main thread). All the UI controls implement ISynchronizeInvoke interface which is meant to do that. So, instead of regular:
progress.Position = 7;
you need to call Invoke:
progress.Invoke(new Action(() => progress.Position = 7), null)
as there is a lot of boiler-plate code I wrote a little extension function for myself:
public static class ControlExtensions
{
public static void Synchronize(this Control control, Action action)
{
if (control == null || !control.InvokeRequired)
{
action();
}
else
{
control.Invoke(action, null);
}
}
}
So now you can just:
progress.Synchronize(() => progress.Position = 7);
(a little bit less typing and easier to read)
Technically, Invoke on ISynchronizeTarget does not really call given action. It just puts a message (good old WM_xxxx) in message queue (but does this in caller's thread) with delegate as argument. Then, if target (control's) thread is processing messages (in its own thread) it gets this WM_xxxx message, calls the delegate (in callers thread - but this time it is UI thread) and returns.
If you need new Thread to call FooHandler, and you don't want to wait use Tasks (it's probably the easiest way):
Task.Factory.StartNew(() => FooHandler.SearchOrWhatever(...));
it won't wait (won't block the UI thread).
Despite all of this being said, don't assume it's done.
Multi-threading is hard. And all those construct which support save you typing, but the hard part is still there: dead-locks, race conditions, starving, etc.
It is possible by calling this function using another thread. If you use .NET 4 take a look at Task object, which will easily solve the issue. If you function return string for example, then you need Task<string> that will call your function. Then depending on your logic you will either block until it's finished or do something similar. If you are using .NET 4.5 then it's even easier with async/await.
My generalized question is this: how do you write asynchronous code that is still clear and easy to follow, like a synchronous solution would be?
My experience is that if you need to make some synchronous code asynchronous, using something like BackgroundWorker, you no longer have a series of easy to follow program statements that express your overall intent and order of activities, you end up instead with a bunch of "Done" Event Handlers, each of which starts the next BackgroundWorker, producing code that's really hard to follow.
I know that's not very clear; something more concrete:
Let's say a function in my WinForms application needs to start up some amazon EC2 instances, wait for them to become running, and then wait for them to all accept an SSH connection. A synchronous solution in pseudo code might look like this:
instances StartNewInstances() {
instances = StartInstances()
WaitForInstancesToBecomeRunning(instances)
WaitForInstancesToAcceptSSHConnection(instances).
return (instances)
}
That's nice. What is happening is very clear, and the order of program actions is very clear. No white noise to distract you from understanding the code and the flow. I'd really like to end up with code that looks like that.
But in reality, I can't have a synchronous solution .. each of those functions can run for a long time, and each needs to do things like: update the ui, monitor for time-outs being exceeded, and retry operations periodically until success or time-out. In short, each of these needs to be happening in the background so the foreground UI thread can continue on.
But if I use solutions like BackgroundWorker, it seems like I don't end up with nice easy to follow program logic like the above. Instead I might start a background worker from my UI thread to perform the first function, and then my ui thread goes back to the UI while the worker thread runs. When it finishes, its "done" event handler might start the next Background Worker. WHen it finishes, its "done" event handler might start the last BackgroundWorker, and so on. Meaning you have to "follow the trail" of the Done Event handlers in order to understand the overall program flow.
There has to be a better way that a) lets my UI thread be responsive, b) let's my async operations be able to update the ui and most importantly c) be able to express my program as series of consecutive steps (as I've shown above) so that someone can understand the resultant code
Any and all input would be greatly appreciated!
Michael
My generalized question is this: how do you write asynchronous code that is still clear and easy to follow, like a synchronous solution would be?
You wait for C# 5. It won't be long now. async/await rocks. You've really described the feature in the above sentence... See the Visual Studio async homepage for tutorials, the language spec, downloads etc.
At the moment, there really isn't a terribly clean way - which is why the feature was required in the first place. Asynchronous code very naturally becomes a mess, especially when you consider error handling etc.
Your code would be expressed as:
async Task<List<Instance>> StartNewInstances() {
List<Instance> instances = await StartInstancesAsync();
await instances.ForEachAsync(x => await instance.WaitUntilRunningAsync());
await instances.ForEachAsync(x => await instance.WaitToAcceptSSHConnectionAsync());
return instances;
}
That's assuming a little bit of extra work, such as an extension method on IEnumerable<T> with the form
public static Task ForEachAsync<T>(this IEnumerable<T> source,
Func<T, Task> taskStarter)
{
// Stuff. It's not terribly tricky :(
}
On the off chance that you can't wait for 5 as Jon rightly suggests, I'd suggest that you look at the Task Parallel Library (part of .NET 4). It provides a lot of the plumbing around the "Do this asynchronously, and when it finishes do that" paradigm that you describe in the question. It also has solid support for error handling in the asynchronous tasks themselves.
Async/await is really the best way to go. However, if you don't want to do wait, you can try Continuation-passing-style, or CPS. To do this, you pass a delegate into the async method, which is called when processing is complete. In my opinion, this is cleaner than having all of the extra events.
That will change this method signature
Foo GetFoo(Bar bar)
{
return new Foo(bar);
}
To
void GetFooAsync(Bar bar, Action<Foo> callback)
{
Foo foo = new Foo(bar);
callback(foo);
}
Then to use it, you would have
Bar bar = new Bar();
GetFooAsync(bar, GetFooAsyncCallback);
....
public void GetFooAsyncCallback(Foo foo)
{
//work with foo
}
This gets a little tricky when GetFoo could throw an exception. The method I prefer is to chage the signature of GetFooAsync.
void GetFooAsync(Bar bar, Action<Func<Foo>> callback)
{
Foo foo;
try
{
foo = new Foo(bar);
}
catch(Exception ex)
{
callback(() => {throw ex;});
return;
}
callback(() => foo);
}
Your callback method will look like this
public void GetFooAsyncCallback(Func<Foo> getFoo)
{
try
{
Foo foo = getFoo();
//work with foo
}
catch(Exception ex)
{
//handle exception
}
}
Other methods involve giving the callback two parameters, the actual result and an exception.
void GetFooAsync(Bar bar, Action<Foo, Exception> callback);
This relies on the callback checking for an exception, which could allow it to be ignored. Other methods have two call backs, one for success, and one for failure.
void GetFooAsync(Bar bar, Action<Foo> callback, Action<Exception> error);
To me this makes the flow more complicated, and still allows the Exception to be ignored.
However, giving the callback a method that must be called to get the result forces the callback to deal with the Exception.
When it finishes, its "done" event handler might start the next Background Worker.
This is something that I've been struggling with for a while. Basically waiting for a process to finish without locking the UI.
Instead of using a backgroundWorker to start a backgroundWorker however, you can just do all the tasks in one backgroundWorker. Inside the backgroundWorker.DoWork function, it runs synchronously on that thread. So you can have one DoWork function that processes all 3 items.
Then you have to wait on just the one BackgroundWorker.Completed and have "cleaner" code.
So you can end up with
BackgroundWorker_DoWork
returnValue = LongFunction1
returnValue2 = LongFunction2(returnValue)
LongFunction3
BackgroundWorker_ProgressReported
Common Update UI code for any of the 3 LongFunctions
BackgroundWorker_Completed
Notify user long process is done
In some scenario (will explain later), you can wrap the async calls to a method like the following pseudo code:
byte[] ReadTheFile() {
var buf = new byte[1000000];
var signal = new AutoResetEvent(false);
proxy.BeginReadAsync(..., data => {
data.FillBuffer(buf);
signal.Set();
});
signal.WaitOne();
return buf;
}
For the above code to work, the call back needs to be invoked from a different thread. So this depends on what you are working with. From my experience, at least Silverlight web service calls are handled in UI thread, which means the above pattern cannot be used - if the UI thread is blocked, the previous begin call even cannot be carried out. If you are working with this kind of frameworks, another way to handle multiple async calls is to move your higher level logic to a background thread and use UI thread for communication. However, this approach is a little bit over killing in most cases because it requires some boilerplate code to start and stop background thread.
I'm trying to provide a functionality of having two Methods one called StartTask(action mymethod)
and the other called StopTask();
problem is the action has to have access to the CancellationTokenSource to check for cancellation and exit the method (return) which is not really what i want the method could be in another component or layer , i cant push every Method to have access to that cancellationtokensource,
i cant push the designer/developer of the component which have the process method to check for cancellation and return.
is there is any way to have something like this , i know it sound strange and inapplicable , just thought of asking.
this is the best i got:
CancellationTokenSource cancellationTokenSource;
private void button1_Click(object sender, EventArgs e)
{
cancellationTokenSource = new CancellationTokenSource();
Task t = new Task(() => Dowork(CancellationAction), cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
t.Start();
}
private bool CancellationAction()
{
if (cancellationTokenSource.IsCancellationRequested)
{
label1.Invoke(new MethodInvoker(() =>
{
label1.Text = "Cancellation Requested!";
}));
return true;
}
return false;
}
private void Dowork(Func<bool> Return)
{
int x = 1;
while (true)
{
x++;
label1.Invoke(new MethodInvoker(() =>
{
label1.Text = x.ToString();
}));
Thread.Sleep(1000);
if (Return())
{
return;
}
}
}
problem with this is DoWork now has to have one parameter which is func , but what if the method already takes other parameters ? the creation of task will be in another class which might not have any idea what parameters to pass beside CancellationAction
If the component does not provide a way to cancel one of its running tasks, then the caller should not be able to cancel it. It could leave the application/database/anything in an unknown state.
So basically the lower level component should provide the caller with a way to cancel a task (ManualResetEvent, CancelAsync method like the BackgroundWorker, etc.). Otherwise the caller should wait for it to finish.
If the lower level component does not provide such a feature, it is most of the time considered as bad design.
I'm not sure that I entirely understand your question, but I'll take a stab at it. It seems like you're trying to solve two problems at once here.
First you're trying to pass parameters to an asynchronous thread and/or cancel that thread (very similar issues). As others have stated BackgroundWorker already handles canceling. That implementation is similar to passing any argument to your thread. If I were replicating that functionality for instance I'd add a Cancel property or method to my worker thread that any other component could call and check a backing value in my main thread loop. No reason to do that for canceling threads these days, just an example of passing and using values to a worker thread.
The other problem that it looks like you need to solve is how to send messages between different parts of your application that shouldn't otherwise need to reference each other. Typically I've seen this done with a service provider of some sort. Implement an interface on a context or common model that all components receive an instance of or have easy access to. The interface should contain any events, methods and properties so the different components can communicate.
E.g. (probably a bad example but...) If my grammar checking routine should cancel when a document is closed, I would define a DocumentClosing event and OnDocumentClosing method on an IDocumentService interface and implement that interface in an appropriate context/model. When creating my document viewer UI component and grammar checker thread component I would inject an instance of the context/model typed as the interface. When the document viewer starts to close the document, it calls the OnDocumentClosing method from the interface. When the thread is created it would attach to the DocumentClosing event and if the event fires a flag is set. Then at intervals while checking grammar, I would check the flag and cancel as appropriate.
This sort of implementation gives you the flexibility to have any component trigger appropriate events and any other component react to them regardless of where in your application the components are used. In fact, this approach is useful even in synchronous situations such as menu items changing state in response to application events. It allows for easy unit testing of all your components. And the segregation of responsibility means that you can easily change any of the trigger points and responses as needed.
Why don't you use BackgroundWorkerThread or other threading mechanism?
Is there a particular reason for using Task Parallel Library?
BackgroundWorkerThread will give you a change to cancel the task and then respond to cancellation.