Generated asynchronous method calls in C# - AOP? - c#

I am working on an WPF application that uses a BusinessLogic layer (currently a single dll) in which I created my BL methods that will be called directly from the UI. Each BL manager is resolved with Unity (thinking on switching to MEF though...). BL classes implements a specific interface that have of course apropriate methods.
Now, what I want is to create (or rather to GENERATE) a new asynchronous-aspect-like assembly (or more...) that should have similar methods/operations defined as in my original assembly (the same parameters...) and also a callback delegate as a parameter.
So basically I want async methods to be generated with some framework out there...
Besides the usual call to:
User userBO = Resolve().Login("name", "pass");
I'd like to use something similar with:
Resolve().Login("name", "pass", delegate(object, SomeArgs e) { User userBO = e.Args....};
Now, I want this assembly to be generated instead of writing new eventArgs and delegates for each method.
I am aware that PostSharp could help in AOP task, but I coulnd't find anything regarding this code generation mechanism in a new dll for asynchronous methods.
Is there a way to achieve this using a third party tool or do I have to rewrite the whole async thing manually?
Any ideas are welcome.
Thank you.

I'm not aware of a tool that will do this for you, but there's an easy way to wrap them in Task objects. This is easier at least than manually defining Async methods and event callbacks.
The general concept is to run the method as a Task and then schedule a task continuation to the UI thread.
First, define a scheduler (you don't need to do this every time; it could be a global var or a window-level var):
TaskScheduler ui = TaskScheduler.FromCurrentSynchronizationContext();
then when you want to call a method and handle its return value:
var bll = Resolve();
Task.Factory.StartNew(_ => bll.Login("name", "pass"))
.ContinueWith(task =>
{
// Note: accessing Result will raise any exceptions thrown by Login
User userBO = task.Result;
...
}, ui);
It's not quite as pretty as your suggested syntax, but it's usable. The task continuation passed to ContinueWith will run on the UI thread, so it is safe to update the UI or any databound objects.
Task objects also fully support other common asynchronous scenarios, in particular cancellation and progress reporting.
Since this approach doesn't actually add events to the class, it should be possible to write a T4 template to generate extension methods for you (e.g., LoginTask(string username, string password, Action<Task<User>> continuation)).

Related

The proper way to await databound property getters c#

What would be the most correct way to use async method in databound property getter? I am talking about solid, scientific arguments, not personal preferences. I've read many threads about the problem, but not this specific case. Some of the solutions don't work in all the cases, and some of the suggestion, well... they were just too subjective or just wrong.
What I don't accept and why:
You can't - Actually, it is possible. There are many posts like "there are no such things like async properties", "it is against the design of the language" etc. but also there are many sensible explanations why such expressions are false
This should me method, not property - It can't be. I want to databind it. I provide property "proxies" for people using this code because in the future there may be different method to calculate this pseudo-property. And I want the View-side of the binding to be simple as possible
Use property to store the cached result of the method - that would defeat the purpose, it is actually something that changes dynamically and the class is an ORM Entity so it would store redundant data to the DB.
Use SomeTask.Result; or SomeTask.GetAwaiter().GetResult() - In most cases I would just use it. I've successfully used those in many cases i.e. Console applications. It's nice, clear and easily readable. But when I use it in databound property I get a deadlock
Problem background (simplified)
Let's say that I am responsible for developing ORM mechanism in a project. There was a first stable version, but now I want to add some properties to the Entities for the DataBinders who are responsible for the layout. I can edit Entity layer, but I can't edit Mapping and Repository layers. (I am not held againt my will, this situation is fictional simplification). All the methods in repositories are async. All I can do is ask someone responsible to provide identical synchronous methods for all of the methods, but it would be stupid to this kind of redundant work.
Only solution I can use now
_something = Task.Run(async () => await AnotherRepository.CalculateStuff(this)).Result;
And it just doesn't look right to me. It works, but I have to await my method inside the lambda in Task.Run(). I am stuck with it for the time being, and I want to know the simplest and correct approach.
Repository method pseudo-code
public async static Task<IList<CalculatedStuff>> CalculateStuff(SomeClass class)
{
return await Task.Run(() =>
{
using (var session = Helper.OpenSession())
return session.CreateCriteria(typeof(CalculatedStuff)).Add(Restrictions.Eq("SomeClass", class))
///...
.List<CalculatedStuff>();
});
}
there are no such things like async properties
I have a blog post and MSDN article on "async properties" for data binding. I do take the stance that they are not natural, which is based on these (objective) observations:
Properties read by data binding must return immediately (synchronously).
Asynchronous operations are asynchronous (that is, they complete after some time).
Clearly, these are at complete odds with one another.
Now, there are a few different solutions, but any solution that attempts to violate one of these observations is going to be dubious, at best.
For example, you can attempt to violate the second observation by trying to run the asynchronous operation synchronously. As you discovered, Result / Wait / GetAwaiter().GetResult() will deadlock (for reasons described in detail on my blog). Task.Run(() => ...).GetAwaiter().GetResult() will avoid the deadlock but will execute the code in a free-threaded context (which is OK for most code but not all). These are two different kinds of sync-over-async; I call them the "Blocking Hack" and the "Thread Pool Hack" in my Async Brownfield article, which also covers two other kinds of sync-over-async patterns.
Unfortunately, there is no solution for sync-over-async that works in every scenario. Even if you get it to work, your users would get a substandard experience (blocking the UI thread for an indefinite amount of time), and you may have problems with app stores (I believe MS's at least will actively check for blocking the UI thread and auto-reject). IMO, sync-over-async is best avoided.
However, we obviously cannot violate the first observation, either. If we're data binding to the result of some asynchronous operation, we can't very well return it before the operation completes!
Or can we?
What if we change what the data binding is attaching to? Say, introduce a property that has a default value before the operation is completed, and changes (via INotifyPropertyChanged) to the result of the operation when the operation completes. That sounds reasonable... And we can stick in another property to indicate to the UI that the operation is in progress! And maybe another one to indicate if the operation failed...
This is the line of thinking that resulted in my NotifyTaskCompletion type in the article on data binding (updated NotifyTask type here). It is essentially a data-bindable wrapper for Task<T>, so the UI can respond dynamically to the asynchronous operation without trying to force it to be synchronous.
This does require some changes to the bindings, but you get a nice side effect that your UX is better (non-blocking).
This should me method, not property
Well, you can do this as a property:
TEntity Entity { get { return NotifyTask.Create(() => Repository.GetEntityAsync()); } }
// Data bind to Entity.Result for the results.
// Data bind to Entity.IsNotCompleted for a busy spinner.
However, I would say that it's surprising behavior to have a property read kick off something significant like a database query or HTTP download. That's a pretty wide definition of "property". IMO, this would be better represented as a method, which connotates action more than a property does (or perhaps as part of an asynchronous initialization, which I also describe on my blog). Put another way: I prefer my properties without side effects. Reading a property more than once and having it return different values is counterintuitive. This final paragraph is entirely my own opinion. :)
If you have access to the source code of AnotherRepository.CalculateStuff, you can implement it in a way that won't deadlock when called from bound property. First short summary of why it deadlocks. When you await something, current synchronization context is remembered and the rest of the method (after async) is executed on that context. For UI applications that means the rest of the method is executed on UI thread. But in your case UI thread is already blocked by waiting for the Result of task - hence deadlock.
But there is method of Task named ConfigureAwait. If you pass false for it's only argument (named continueOnCapturedContext) and await task returned by this method - it won't continue on captured context, which will solve your problem. So suppose you have:
// this is UI bound
public string Data
{
get { return GetData().Result; }
}
static async Task<string> GetData() {
await Task.Run(() =>
{
Thread.Sleep(2000);
});
return "test!";
}
This will deadlock when called from UI thread. But if you change it:
static async Task<string> GetData() {
await Task.Run(() =>
{
Thread.Sleep(2000);
}).ConfigureAwait(false);
return "test!";
}
It won't any more.
For those who might read this later - don't do it this way, only if for temporary debugging purposes. Instead return dummy object from your property getter with some IsLoading flag set to true, and meanwhile load data in background and fill dummy object properties when done. This will not freeze your UI during long blocking operation.

Communicating between view and view model using ReactiveUI.NET

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.

How to properly write a custom Task returning method

For running code asynchronously (eg with async/await) I need a proper Task. Of course there are several predefined methods in the framework which cover the most frequent operations, but sometimes I want to write my own ones. I’m new to C# so it’s quite possible that I’m doing it wrong but I’m at least not fully happy with my current practice.
See the following example for what I’m doing:
public async Task<bool> doHeavyWork()
{
var b1 = await this.Foo();
//var b2 = await Task<bool>.Factory.StartNew(Bar); //using Task.Run
var b2 = await Task.Run(()=>Bar());
return b1 & b2;
}
public Task<bool> Foo()
{
return Task.Factory.StartNew(() =>
{
//do a lot of work without awaiting
//any other Task
return false;
});
}
public bool Bar()
{
//do a lot of work without awaiting any other task
return false;
}
In general I create and consume such methods like the Foo example, but there is an ‘extra’ lambda containing the whole method logic which doesn't look very pretty imho. Another option is to consume any Method like the Bar example, however I think that’s even worse because it isn’t clear that this method should be run async (apart from proper method names like BarAsync) and the Task.Factory.StartNew may has to be repeated several times in the program. I don’t know how to just tell the compiler ‘this method returns a Task, please wrap it as a whole into a Task when called’ which is what I want to do.
Finally my question: What’s the best way to write such a method? Can I get rid of the ‘extra’ lambda (without adding an additional named method of course)?
EDIT
As Servy stated there is always good reason to have a synchronous version of the method. An async version should be provided only if absolutley necessary (Stephen Cleary's link).
Would the world end if someone wanted to call Bar without starting it in a new thread/Task? What if there is another method that is already in a background thread so it doesn't need to start a new task to just run that long running code? What if the method ends up being refactored into a class library that is called from both desktop app context as well as an ASP or console context? In those other contexts that method would probably just need to be run directly, not as a Task.
I would say your code should look like Bar does there, unless it's absolutely imperative that, under no circumstances whatsoever, should that code be run without starting a new Task.
Also note that with newer versions of .NET you should be switching from Task.Factory.StartNew to Task.Run, so the amount of code should go down (a tad).

Cancellation of a Task without Providing the Task method with the CancellationTokenSource

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.

Async P/Invoke calls

I'm working on a wrapping library for a robot controller, that mostly relies on P/Invoke calls.
However, a lot of the functionality for the robot, such as homing, or movement, takes quite a while, and do thread locks while running.
So I'm wondering how I can wrap the functionality in a async manner, so the calls don't block my UI thread. My idea so far is to use Tasks, but I'm not really sure it's the right approach.
public Task<bool> HomeAsync(Axis axis, CancellationToken token)
{
return Task.Factory.StartNew(() => Home(axis), token);
}
Most of the MSDN articles on the Async model in .NET as of right now, mostly is relaying on libraries already having Async functionality (such as File.BeginRead and so on). But I can't seem to find much information on how to actually write the async functionality in the first place.
After some great discussion, I think something like this will be the golden middleway.
public void HomeAsync(Axis axis, Action<bool> callback)
{
Task.Factory
.StartNew(() => Home(axis))
.ContinueWith(task => callback(task.Result));
}
This is using the best of both worlds, I think.
Have you ever tried async delegates? I believe there is nothing simpler than it.
If your thread-blocking method is void Home(Axis) you have first to define a delegate type, ie. delegate void HomeDelegate(Axis ax), then use the BeginInvoke method of a new instance of HomeDelegate pointing to the address of Home method.
[DllImport[...]] //PInvoke
void Home(Axis x);
delegate void HomeDelegate(Axis x);
void main()
{
HomeDelegate d = new HomeDelegate(Home);
IAsyncResult ia = d.BeginInvoke(axis, null, null);
[...]
d.EndInvoke(ia);
}
Please bear in mind that using the EndInvoke somewhere (blocking the thread until the method is finally over, maybe in conjunction with polling of IAsyncResult.Completed property) is very useful to check if your async task has really been completed. You might not want your robot to open its arm and leave a glass until the glass is over the table, you know ;-)
My first reaction is that this is not something you should do in the library. The primary reason is that the way you implement such a system may depend on the type of interface you are building upon the library.
That said, you have basically two choices. First is the IAsyncResult. A good description of this can be found at http://ondotnet.com/pub/a/dotnet/2003/02/24/asyncdelegates.html.
The second option is to create commands with callback events. The user creates a command class and sets a callback on that. Then, you schedule the command to a ThreadPool and after the command has been executed, you raise that event.
Older interfaces of the .NET framework primarily implemented the IAsyncResult approach, where newer interfaces tend to implement the event callback approach.

Categories