Best solution for async chicken and egg story - c#

I have been applying async best practices to all my libraries. Basically it means:
Only use async when it's truly async (libraries shouldn't lie)
Define a synchronous method if and only if you have a faster synchronous method that won’t dead lock.
Postfix all async methods with Async
I worked on a library that is synchronous by nature. This means it has only sync methods. If the user wants to run the work on a separate thread than the UI thread, they can do that themselves by using Task.Factory (responsibility of the caller).
However, inside a handler / method / extensibility point, we want to show the user a message box. This is an async method (for example, WinRT ShowDialogAsync). Then this gives us the following options:
A. Move everything to async (so we have the option to use await in our handlers and don't block anything).
public async Task MyMethodAsync()
{
await _messageService.ShowAsync();
}
The advantage is that users can add async methods without having to use .Wait(). The downside is that we are lying as a library (it's not truly async).
I have considered making everything async, but I don't think that's a good idea either. It would make all libraries lie but prepare them in case we would need it. Remember that making everything async out of the box has a (small) performance impact as well.
B. Inside the handler that requires user input, call .Wait()
public void MyMethod()
{
_messageService.ShowAsync().Wait();
}
The advantage is that this will allow us to use async code inside sync methods. But... it will never be callable from the UI-thread because the _messageService dispatches to the UI thread (but it cannot do that because it's still waiting for the method, resulting in a deadlock). This method will work when used inside a Task.Factory.Run block (but the responsibility is up to the end-user):
await Task.Factory.Run(() => MyMethod());
The question
I feel that both have pros and cons, but what would you choose? Let the library lie (A) or only allow the method to be called from a background thread (B)? Or maybe there are other options I've overseen.
If I go for A, it means I have to bump the major version every time (because it's actually a breaking change) whenever a user requests to convert a method to an async signature method.

Define a synchronous method if and only if you have a faster synchronous method that won’t dead lock.
I'd say "define a synchronous method if you have synchronous work to do". It doesn't matter how fast it is. The burden is on the caller to determine if it's too slow and they need to use Task.Run.
However, inside a handler / method / extensibility point
If this is an Observer kind of extensibility, consider just using events or observables.
However, it sounds like you want more of a Strategy kind of extensibility, where your invoking code must wait for and/or change its behavior based on the result of the callback.
I have considered making everything async, but I don't think that's a good idea either.
Async all the way is a guideline, not a strict command. It definitely applies in the 99% case, but this could be one of the exceptions. I would try not to make a library async just for the sake of a possibly-async Strategy pattern; I'd investigate other extension possibilities first. There is a valid argument for making the library async, if you view the Strategy callback as a dependency (the library would be async because its dependency is (possibly) async).
As you've discovered, there's no clean way to do sync-over-async. There are a few different hacks (such as blocking from a background thread), but you'll first need to decide whether you need to call your library from the UI thread.
If you do, then there's just two options: make the library async, or use a nested message loop. I strongly avoid nested message loops, especially in libraries; I'm just mentioning it for sake of completeness.
If you can impose on the user a requirement to only call the library from a non-UI thread, then you can apply other hacks. E.g., blocking the background thread.
There's not an easy solution, sorry.
As far as me personally... if the library needs an async Strategy, then I would lean towards making the library async. But it does depend on what kind of library it is, whether there were backwards-compatibility issues, etc. And the first thing I'd look into is a different kind of extensibility point.

as you can read here :
https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
Async All the Way
Asynchronous code reminds me of the story of a fellow who mentioned that the world was suspended in space and was immediately challenged by an elderly lady claiming that the world rested on the back of a giant turtle. When the man enquired what the turtle was standing on, the lady replied, “You’re very clever, young man, but it’s turtles all the way down!” As you convert synchronous code to asynchronous code, you’ll find that it works best if asynchronous code calls and is called by other asynchronous code—all the way down (or “up,” if you prefer). Others have also noticed the spreading behavior of asynchronous programming and have called it “contagious” or compared it to a zombie virus. Whether turtles or zombies, it’s definitely true that asynchronous code tends to drive surrounding code to also be asynchronous. This behavior is inherent in all types of asynchronous programming, not just the new async/await keywords.
“Async all the way” means that you shouldn’t mix synchronous and asynchronous code without carefully considering the consequences. In particular, it’s usually a bad idea to block on async code by calling Task.Wait or Task.Result. This is an especially common problem for programmers who are “dipping their toes” into asynchronous programming, converting just a small part of their application and wrapping it in a synchronous API so the rest of the application is isolated from the changes. Unfortunately, they run into problems with deadlocks. After answering many async-related questions on the MSDN forums, Stack Overflow and e-mail, I can say this is by far the most-asked question by async newcomers once they learn the basics: “Why does my partially async code deadlock?”

Related

Is using Task.Run a bad practice?

Generally, when implementing an asynchronous method on a class, I write something like this:
public Task<Guid> GetMyObjectIdAsync(string objectName)
{
return Task.Run(() => GetMyObjectId(objectName));
}
private Guid GetMyObjectId(string objectName)
{
using (var unitOfWork = _myUnitOfWorkFactory.CreateUnitOfWork())
{
var myObject = unitOfWork.MyObjects.Single(o => o.Name == objectName);
return myObject.Id;
}
}
This sort of pattern allows me to use the same logic synchronously and asynchronously, depending on the situation (most of my work is in an old code base, not a lot supports async calls yet), as I could expose the synchronous method publicly and get maximum compatibility if I need to.
Recently I've read several SO posts that suggest using Task.Run() is a bad idea, and should only be used under certain circumstances, but those circumstances did not seem very clear.
Is the pattern I've depicted above actually a bad idea? Am I losing some of the functionality/ intended purpose of async calls doing it this way? Or is this a legit implementation?
What you are doing is offloading a synchronous operation to another thread. If your thread is "special" then that's perfectly fine. One example of a "special" thread is a UI thread. In that case you may want to offload work off of it to keep the UI responsive (another example is some kind of listener).
In most cases however you're just moving work around from one thread to another. This doesn't add any value and does add unnecessary overhead.
So:
Is the pattern I've depicted above actually a bad idea?
Yes, it is. It's a bad idea to offload synchronous work to the ThreadPool and pretend as if it's asynchronous.
Am I losing some of the functionality/ intended purpose of async calls doing it this way?
There's actually nothing asynchronous about this operation to begin with. If your executing this on a remote machine and you can benefit from doing it asynchronously the operation itself needs to be truly asynchronous, meaning:
var myObject = await unitOfWork.MyObjects.SingleAsync(o => o.Name == objectName);
What you're currently doing is called "async over sync" and you probably shouldn't do it. More in Should I expose asynchronous wrappers for synchronous methods?
Recently I've read several SO posts that suggest using Task.Run() is a bad idea, and should only be used under certain circumstances, but those circumstances did not seem very clear.
The absolutely bare bones rules of thumb I tell people who are new to asynchrony is:
First, understand the purpose. Asynchrony is for mitigating the important inefficiencies of high-latency operations.
Is the thing you're doing low-latency? Then don't make it asynchronous in any way. Just do the work. It's fast. Using a tool to mitigate latency on low-latency tasks is just making your program unnecessarily complex.
Is the thing you're doing high-latency because it is waiting on a disk to spin or a packet to show up? Make this asynchronous but do not put it on another thread. You don't hire a worker to sit by your mailbox waiting for letters to arrive; the postal system is already running asynchronously to you. You don't need to hire people to make it more asynchronous. Read "There Is No Thread" if that's not clear.
Is the high-latency work waiting on a CPU to do some enormous computation? Like a computation that is going to take well over 10 ms? Then offload that task onto a thread so that the thread can be scheduled to an idle CPU.
public Task<Guid> GetMyObjectIdAsync(string objectName)
When I see this, I expect there to be some advantage in using this method rather than just wrapping it in Task.Run() myself.
In particular, I'd expect it to release the thread when it hits some I/O or otherwise has the opportunity to do so.
Now consider if I have the code:
_resource = GetResourceForID(GetMyObjectIdAsync(SomeLongRunningWayToGetName()));
If I have a reason to need to have this done in a task, and I'm in the sort of situation where Task.Run() does actually make sense (I have a reason to offload it onto another thread) the best way to do this would be to wrap the whole thing:
Task task = Task.Run(() => _resource = GetResourceForID(GetMyObjectIdAsync(SomeLongRunningWayToGetName())));
Here Task.Run() might be a bad idea for me as the caller, or it might be good because I really am gaining from what it gives me.
However, if I see your signature I'm going to think that the best way to do this with your code would be to turn it into code that uses that method.
Task task = SomeLongRunningWayToGetName()
.ContinueWith(t => GetMyObjectIdAsync(t.Result))
.ContinueWith(t => _resource = GetResourceForIDAsync(t.Result));
(Or similar using async and await).
At best this has less good chunking of the Task.Run(). At worse I'm awaiting this just to gain from the better asynchronicity that it doesn't offer in a context that could make use of it if it was really there. (E.g I might have used this in an MVC action that I'd made asynchronous because I thought the extra overhead would be repaid in better thread-pool use).
So while Task.Run() is sometimes useful, in this case it's always bad. If you can't offer me greater asynchronicity than I can bring to the use of the class myself, don't lead me to believe you do.
Only offer a public XXXAsync() method if it really does call into asynchronous I/O.
If you really need to stub out an asynchronous method to e.g. match a signature of a shared base or interface, then it would be better as:
public Task<Guid> GetMyObjectIdAsync(string objectName)
{
return Task.FromResult(GetMyObjectId(objectName);
}
This is bad too (the caller would still have been better off just calling GetMyObjectId() directly), but at least if code awaits it then while it operates on the same thread there's no overhead of using yet another thread to do the work, so if it's mixed in with other awaits the negative impact is reduced. It's therefore useful if you really need to return a Task but can't add anything useful in how you call it.
But if you don't really need to offer it, just don't.
(A private method calling Run() because you every call site benefits from it is different, and there you're just adding convenience rather than calling Run() in several places, but that should be well-documented as such).

Correct way to rewrite my Utils library with Async/Await

I have a lot of Utils classes that I use for many different projects, most of them are static and made out of static methods that usually don't even call each others.
My intention is to take advantages from the new async/await features but without rewriting everything, so my question is: can I just add a new method for each existing method named MethodAsync with the Task.Run(() => MethodName)?
example:
//old code that will not be removed
static void DoSomething()
{ ... }
//new code that will be added
static async Task DoSomethingAsync()
{
//not really sure if Im supposed to use await/async here.
//isn't Task awaitable even without async??
return await Task.Run(() => DoSomething());
}
Basically in the old code I just had a normal sync method while in the new one I have an async method that could even run in another thread if the CLR see it as a CPU-bound method.
If I correctly understand, every asyncronous method contains by definition an await to an awaitable object which is a Task or another asyncronous method.
that means that whenever I can use an async .NET method, I should await it and mark my caller method as async.
But, every other method that do not call any async method but could take some time to complete should be called with a Task.Run call.
right?
EDIT
so I have read all the posted links, the best practices on msdn and a few blog posts but I still need a complete routine to follow when coding with the new async/await feature.
this is what I get so far:
1) every .NET method that has an async alternative should use the async alternative. (As far as I know the .NET async methods already exists ONLY for methods that can be async).
2) every method that use async methods should be made async too.
3) every method that do not use async methods (cause there aren't available) but still takes some cpu-time to execute should be made async by wrapping them using Task.Run (I understand that in this case it should be the client to use Task.Run if they want but since im only adding these wrappers for methods that takes more than 50ms to execute and there will be still available the non-async version of the method, I still don't see why I shouldn't place this wrapper in the library).
4) every method that takes non-cpu-time cause it's waiting for other sources (like internet, database, events, etc...) should use TaskFactory.FromAsync or TaskCompletionSource.
5) System.Threading.Tasks.Parallel.Invoke(method1, method2, etc...) is now deprecated. From what I read Task.Run already run concurrent threads if the CLR thinks that concurrency is required. So it seems that Task.Run already uses Parallel.Invoke when needed.
I was finally able to find good resources that cleared all my doubts:
the first one is "The Task-based Asynchronous Pattern" available at http://www.microsoft.com/en-us/download/details.aspx?id=19957
This document explains the async/await feature, how/when to use it, it contains many practical examples and a few of very usefull static methods that im now using on every project!
The second one is "The zen of async: Best practices for best performance" available at http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-829T
which is a complete overview of the async feature, with some coverage of the Parallel features and it also explains why it should never be the library that use Task.Run() method but it should be a consumer choice instead.
So in the end I was really confusing multithreading with asynchronous code and I couldn't grasp the advantages of async code because I was just looking at 1 single method at the time while the real benefits of async code can only be seen if the entire project (or at least a consistent portion of it) is written following the async pattern.
For example in asp.net, if there isn't any blocking code (everything written in a async fashion way), then a thread can serve another client while yours is awaiting an async operation, improving scalability, while in a xaml application a thread that launch an async operation can immediately go back to supporting your UI instead of just waiting that operation to be over, improving responsiveness.
This has been discussed in Should I expose asynchronous wrappers for synchronous methods? The part of this article that I thought highlighted why this is bad design is below:
Consider, for example, a simple method like Dictionary<TKey,TValue>.Add(TKey,TValue). This is a really fast method, right? Typically, yes, but remember how dictionary works: it needs to hash the key in order to find the right bucket to put it into, and it needs to check for equality of the key with other entries already in the bucket. Those hashing and equality checks can result in calls to user code, and who knows what those operations do or how long they take. Should every method on dictionary have an asynchronous wrapper exposed? That’s obviously an extreme example, but there are simpler ones, like Regex. The complexity of the regular expression pattern provided to Regex as well as the nature and size of the input string can have significant impact on the running time of matching with Regex, so much so that Regex now supports optional timeouts… should every method on Regex have an asynchronous equivalent? I really hope not.
Obviously I advise you to read the entire article too, but I hope the above highlights a great reason why exposing *Async() methods should not wrap synchronous ones in a library.
I hope this helps.

how is async modifier and await operator different from delegates and threading?

For example a scenario in Winform where the UI thread will be blocked while we use
HttpWebRequest synchronously which in turn requests resources on Internet. Here we can use async method to execute the method while await keyword for certain task allows user to interact with winform even though the request is still running.
This can even be achieved by delegation so what's the advantage of Async Feature?
One of the nicest advantages in my opinion is a more concise way to understand the async programming pattern with less lines of code. If you want to see more clearly how it works, check out this question answered by Jon Skeet: How does Task<int> become a int?
The async and await termonoligy is much simpler and you can basicaly write your code just as you would do a syncronious application by just adding some keywords.
From MSDN:
You can avoid performance bottlenecks and enhance the overall
responsiveness of your application by using asynchronous programming.
However, traditional techniques for writing asynchronous applications
can be complicated, making them difficult to write, debug, and
maintain.
Visual Studio 2012 introduces a simplified approach, async
programming, that leverages asynchronous support in the .NET Framework
4.5 and the Windows Runtime. The compiler does the difficult work that the developer used to do, and your application retains a logical
structure that resembles synchronous code. As a result, you get all
the advantages of asynchronous programming with a fraction of the
effort.
http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx
I assume by "delegation" you mean to call the synchronous methods from a background thread.
As others have pointed out, the code is easier to read and write using async and await, but there's another important difference as well.
When you use synchronous methods, the calling thread is blocked until the operation is complete.
When you use synchronous methods from a background thread, the UI thread is not blocked but the background thread still is.
When you use asynchronous methods, no threads are blocked. This allows more efficient usage of your resources, with less pressure on the thread pool.

Async CTP - Recommended approach for task scheduling

I'm currently working on a largely asynchronous application which uses TAP throughout. Every class which has methods for spawning Tasks also has a TaskScheduler injected into it. This allows us to perform explicit scheduling of tasks, which as I understand, is not the way Microsoft are going with the Async CTP.
The only issue I have with the new approach (implicit scheduling) is that our previous philosophy has always been "we know the continuation will always specify their task scheduler, so we don't need to worry about what context we complete the task on".
Moving away from that does worry us slightly just because it has worked extremely well in terms of avoiding subtle threading errors, because for every bit of code we can see that the coder has remembered to consider what thread he's on. If they missed specifying the task scheduler, it's a bug.
Question 1: Can anyone reassure me that the implicit approach is a good idea? I see so many issues being introduced by ConfigureAwait(false) and explicit scheduling in legacy/third party code. How can I be sure my 'await-ridden' code is always running on the UI thread, for example?
Question 2: So, assuming we remove all TaskScheduler DI from our code and begin to use implicit scheduling, how do we then set the default task scheduler? What about changing scheduler midway through a method, just before awaiting an expensive method, and then setting it back again afterward?
(p.s. I have already read http://msmvps.com/blogs/jon_skeet/archive/2010/11/02/configuring-waiting.aspx)
I'll take a shot at answering. ;)
Question 1: Can anyone reassure me that the implicit approach is a good idea? I see so many issues being introduced by ConfigureAwait(false) and explicit scheduling in legacy/third party code. How can I be sure my 'await-ridden' code is always running on the UI thread, for example?
The rules for ConfigureAwait(false) are pretty simple: use it if the rest of your method can be run on the threadpool, and don't use it if the rest of your method must run in a given context (e.g., UI context).
Generally speaking, ConfigureAwait(false) should be used by library code, and not by UI-layer code (including UI-type layers such as ViewModels in MVVM). If the method is partially-background-computation and partially-UI-updates, then it should be split into two methods.
Question 2: So, assuming we remove all TaskScheduler DI from our code and begin to use implicit scheduling, how do we then set the default task scheduler?
async/await does not normally use TaskScheduler; they use a "scheduling context" concept. This is actually SynchronizationContext.Current, and falls back to TaskScheduler.Current only if there is no SynchronizationContext. Substituting your own scheduler can therefore be done using SynchronizationContext.SetSynchronizationContext. You can read more about SynchronizationContext in this MSDN article on the subject.
The default scheduling context should be what you need almost all of the time, which means you don't need to mess with it. I only change it when doing unit tests, or for Console programs / Win32 services.
What about changing scheduler midway through a method, just before awaiting an expensive method, and then setting it back again afterward?
If you want to do an expensive operation (presumably on the threadpool), then await the result of TaskEx.Run.
If you want to change the scheduler for other reasons (e.g., concurrency), then await the result of TaskFactory.StartNew.
In both of these cases, the method (or delegate) is run on the other scheduler, and then the rest of the method resumes in its regular context.
Ideally, you want each async method to exist within a single execution context. If there are different parts of the method that need different contexts, then split them up into different methods. The only exception to this rule is ConfigureAwait(false), which allows a method to start on an arbitrary context and then revert to the threadpool context for the remainder of its execution. ConfigureAwait(false) should be considered an optimization (that's on by default for library code), not as a design philosophy.
Here's some points from my "Thread is Dead" talk that I think may help you with your design:
Follow the Task-Based Asynchronous Pattern guidelines.
As your code base becomes more asynchronous, it will become more functional in nature (as opposed to traditionally object-oriented). This is normal and should be embraced.
As your code base becomes more asynchronous, shared-memory concurrency gradually evolves to message-passing concurrency (i.e., ConcurrentExclusiveSchedulerPair is the new ReaderWriterLock).

WP7- Confused about network communication, cross thread access, and continuation passing

I'm porting a WPF app to WP7, and in the process I've had to refactor all the code that touches the network. The old code used the synchronous methods of the WebRequest object in background threads, but these methods no longer exist in WP7.
The result has been bewildering, and makes me feel like I'm doing something wrong. I've had to litter my views with thread dispatching code - the only alternative to this that I see is to supply the dispatcher to the lower tiers of the app, which would break platform-independence and muddy the boundary with the UI. I've lost the ability to make chained calls over the network from loops, and instead have callbacks invoking themselves. I've lost try/catch error handling and instead have OnSuccess and OnError callbacks everywhere. I'm now always unintentionally running code in background threads that are invoked by callbacks. I fondly remember the days when I was able to return values from methods.
I know continuation-passsing-style is supposed to be great, but I think all of the above has made the code more brittle and less readable, and has made threading issues more complex than they need to be.
Apologies if this question is vague, I'd just like to know if I'm missing some big picture here.
This is a limitation of Silverlight, which requires asynchronous network access (WCF proxy calls, WebClient, WebRequest, etc.). All synchronous network-reliant method calls have been removed from the framework.
To be crass: welcome to asynchronous programming. The only thing you did wrong was not making the calls asynchronous in the first place :)
I'm not 100% clear on the exact reasons MS removed the sync calls from web-dependent objects in Silverlight, but the explanations I hear always center on one or two reasons in some combination:
Browsers are architected on asynchronous network calls. Introducing synchronous calls would cause bad behavior/broken apps/crashes/etc.
If they gave everyone the "easy out" of making synchronous calls, the world would be littered with Silverlight apps that always froze while doing anything on the network, making Silverlight as a platform look bad.
That said - WCF proxies in Silverlight have the behavior that they always perform their callback on the calling thread. This is most often the UI thread, meaning you don't have to do any dispatching. I do not know if WebClient/WebRequest in Silverlight share this behavior.
As for the dispatcher, you could look into using a SynchronizationContext instead. The MVVM reference implementation in the MS Patterns and Practices Prism guidance does this - in the repository (data access class that actually makes calls out to an abstracted external service), they have a SynchronizationContext member that is initialized to System.Threading.SynchronizationContext.Current. This is the UI thread, if the constructor is called on the UI thread (it should be). All results from the service calls are then handled with mySynchronizationContext.Post.
Questions like this seem to behave like buses. You don't see any for ages then two come along almost at the same time. See this answer to a more concrete version of this question asked earlier today.
I have to I agree with you, continuation passing is tricky. A really useful technique is to borrow the C# yield return construct to create a machine that is able to maintain state between asynchronous operations. For a really good explanation see this blog by Jeremy Likness.
Personally I prefer a "less is more" approach so the AsyncOperationService is a very small chunk of code. You'll note that it has a single callback for both success and failure and there no interfaces to implement just a moderate delegate Action<Action<Exception>> which is typed as AsyncOperation to make it more convenient.
The basic steps to coding against this are:-
Code as if synchronous execution were possible
Create methods that return an AsyncOperation fpr only the smallest part that has to be asynchronous. Usually some WebRequest or WCF call but note just enough to get past the async bit, see me other answer for a good example.
Convert the synchronous "psuedo-code" to yeild these AsyncOperations and change the calling code to "Run" the resulting enumerable.
The final code looks quite similar to the synchronous code you might be more familar with.
As to accidentally running things on a background thread, that last answer included this useful AsyncOperation:-
public static AsyncOperation SwitchToUIThread()
{
return (completed => Deployment.Current.Dispatcher.BeginInvoke(() => completed(null)));
}
You can use that as the final yield in the run to ensure that code executing in the completed callback is executing on the UI thread. Its also useful to "flip" what is apparently synchronous code to be running on the UI thread when necessary.

Categories