At the last month’s webinar, “Asynchronous Programming Demystified” Stephen Cleary, Microsoft MVP, and author of “Concurrency in C# Cookbook” introduced the async and await keywords and describes how they work.
During the webinar, there were a number of great questions asked from viewers that Stephen didn’t have sufficient time to answer. In fact, there were 88 total questions. Fortunately, Stephen was kind enough to provide us with his answers below:
Q: You showed us how to correctly use and call async methods. But how do I create an async API out of nothing?
A: The low-level type for this is TaskCompletionSource
Q: Can we use Async inside LINQ methods (with lambda expressions)?
A: LINQ is inherently synchronous, so there isn’t much you can do asynchronously. E.g., you can use Select with an asynchronous delegate, but that gives you a sequence of tasks, and there isn’t much you can do with them other than using something like Task.WhenAll. If you want an asynchronous sequence or stream abstraction, a better fit would be Reactive Extensions.
Q: What would be the best approach to implement 3rd party synchronous library/API into let’s say our existing asynchronous API? Since we does want to maintain asynchronous should we wrap it into Task Run or something else?
Q: Does async await help with AJAX calls?
A: Async can exist independently on the server and the client. You can use async on the client to help you call AJAX endpoints (i.e., call several of them concurrently). You can also use async on the server to help you implement AJAX endpoints.
Q: Will try-catch around await keyword really catch all exceptions that can be raised within the called async method?
A: Yes; an async method will always place its exceptions on the task it returns, and when you await that task, it will re-raise those exceptions, which can be caught by a regular try/catch.
Q: Is it true that async method is not in fact started until either await, Wait or .Result is called for it?
A: No. An async method starts when it is called. The await/Wait/Result will just wait for the method to complete.
Q: We use MSMQ for a lot of our asynchronous WCF processing. It’s heavy and expensive. Can async/await replace some if not all of the MSMQ processing?
A: Async/await is not a direct replacement for any kind of queuing. You can use async to interact with the queue, though. The MessageQueue class unfortunately does not follow a standard asynchronous pattern, but you can use TaskCompletionSource
Q: IAsyncResult fits very nicely with Windows low level and IOPorts. Does async/await have the same high performance?
Q: Can you explain when it is appropriate to use ConfigureAwait(false)?
A: Anytime that the async method does not need its context, it should use ConfigureAwait(false). This is true for most library code.
Q: Re. Task.Run() blocking a background thread… even using await will block a thread at some point surely?
A: No, await does not block a thread. I have more details in my blog post “There Is No Thread”.
Q: Do you need to tweak machine/web config to get greater throughput for asynchrony?
Q: What about WhenAll?
A: WhenAll can be used to concurrently execute multiple asynchronous operations.
Q: What are the main problems using ContinueWith? There a lot of companies that have this type of implementation because of legacy code.
A: ContinueWith is problematic for several reasons. For one, a single logical method must be broken up into several delegates, so the code is much more difficult to follow than a regular await. Another problem is that the defaults are not ideal; in particular, the default task scheduler is not TaskScheduler.Default as most developers assume – it is in fact TaskScheduler.Current. This unexpected task scheduler can cause issues like the one I describe in my blog post “StartNew Is Dangerous”.
Q: Why is button1_Click using the async keyword, when it is calling the async method?
A: Any method that uses the await keyword must be marked async. Normally, I would make the method an “async Task” method, but since this is an event handler, it cannot return a task, so I must make it an “async void” method instead.
Q: Are there any means to debug async code easily?
A: VS2013 has pretty good support for debugging asynchronous code, and the tooling is continue to improve in this area. The one drawback to async debugging is that the call stack is not as useful. This is not a problem of async; we developers have gotten used to the idea that the call stack is a trace of how the program got to where it is – but that mental model is incorrect; the call stack is actually telling the program where to go next.I have an AsyncDiagnostics library that preserves “how the program got to where it is”, which is sometimes helpful when trying to track down an issue.
Q: In ASP.NET there are many queues. What will happen when system is overloaded, and we fulfill Async IO ports. Will it throw exception or will act it as it would without async?
A: When the queues fill up, it will act the same. Async provides better scalability, but not infinite scalability. So you can still have requests timing out in the queues or being rejected if the queues fill up. Note that when the async request starts, it is removed from the queue, so async relieves pressure on the queues.
Q: Lets say I have an WinForm app. with a method that renders some image that takes 60 secs for example. When the user presses the Begin button, I want to render to occur and later say “Finished” when done, without blocking during the meantime. Can you suggest a strategy?
Q: Is it acceptable to create asynchronous versions of synchronous methods by just calling the synchronous methods with Task.Run
Q: Is it really bad to wrap async code in sync code? I thought that is a very bad practice, but have seen OAuth packages wrapping async code in sync methods with some kind of TaskHelper eg. GetUser is internally using GetUserAsync
A: The problem with library code is that sometimes you do want both asynchronous and synchronous APIs. But you don’t want to duplicate your code base. It is possible to do sync-over-async in some scenarios, but it’s dangerous. You have to be sure that your own code is always using ConfigureAwait(false), and you also have to be sure that any code your code calls also uses ConfigureAwait(false). (E.g., as of this writing, HttpClient does on most platforms but not all). If anyone ever forgets a single ConfigureAwait(false), then the sync-over-async code can cause a deadlock.
Q: If you have large application with lots of different things to do with async how to handle the correct “flow”? So user will not use application in wrong way. Is there best practices for this?
A: The approach I usually use is to just disable/enable buttons as I want them to be used. There is a more advanced system for UI management called Reactive UI (RxUI), but it has a higher learning curve.
Q: Is await produces managed code in .NET? Can we write unmanaged code within await/ async blocks?
A: Await does produce managed (and safe) code. I believe unsafe code can be within an async method (though I’ve never tried it), but await cannot be used within an unsafe code block.
Q: Any advice with use of DAL (sync with MSSQL) to use with async call? Use Task.Run or rewrite
A: I’d recommend using the asynchronous support in EF6 to rewrite the DAL as purely asynchronous. But if you are in a situation where you need UI responsiveness and don’t want to take the time to make it asynchronous, you can use Task.Run as a temporary workaround.
Q: But you do want it for CPU bound code on client UIs (WPF, WinForms, Phone, etc.)
Q: When I am awaiting on several tasks, is it better to use WaitAll or WhenAll?
A: WaitAll can cause deadlock issues if the tasks are asynchronous, just like Result and Wait do. So, I would recommend “await Task.WhenAll(…)” for asynchronous code.
Q: You say await Task.Run(() => Method() is Ok to do… I’m assuming it’s not best practice or just not the way Stephen uses? I guess is it a common or personal practice?
Q: Can you explain the Server Side Scalability benefit a little more?
Q: If there is a use case where i have to call async call from synchronous code, what is the best way to do that?
A: “There is no good way to do sync-over-async that works in every scenario. There are only hacks, and there are some scenarios where no hack will work. So, for sure, the first and best approach is to make the calling code async; I have a blog post series on “async OOP” that covers ways to make it async even if it doesn’t seem possible at first.
If you absolutely must do sync-over-async, there are a few hacks available. You can block on the async code (e.g., Result); you can execute the async code on a thread pool thread and block on that (e.g., Task.Run(() => …).Result); or you can do a nested message loop. These approaches are all described in Stephen Toub’s blog post “Should I Expose Synchronous Wrappers for My Asynchronous Methods?”
Q: Would “unit testing” be part of “Async Best Practices”? As in, would you be giving tips on best way to unit test in that future proposed webinar?
Q: What is the appropriate way to unit test an async method?
Q: The benefit : “Responsiveness on the client side” sounds like a background process. I thought async wasn’t a background thing…
Q: I’ve read and heard often that another thread is not created. I’m struggling to understand how I/O is occurring without a thread managing it while the main thread is released. I comprehend how it gets back, i.e. an event of sorts picking up on the stack where it left off.
A: I have a blog post “There Is No Thread” that explains this in detail.
Q: When you implementing the IUserStore for the Identity, there are things that require you to implement a Task returning async method, however, I don’t see any need to call async method. Task
A: Normally, I/O is asynchronous. So “saving” a user is an inherently I/O-bound operation, and should be asynchronous if possible. If you truly have a synchronous implementation (e.g., saving the user in memory as part of a unit test), then you can implement the asynchronous method by using Task.FromResult.
Q: Does Await spin a new thread under the hoods?
Q: What is the best way to call Async Methods from class constructors?
Q: Shouldn’t the Click event handler be also renamed to ClickAsync?
Q: Is it possible to communicate progress from the async task?
A: Yes. An asynchronous method can report progress by taking an IProgress
Q: How would unit/integration test code coverage influence designs and usage of async/await?
Q: So if my UI uses await/async to call a WebAPI method, the method itself has to be async or else it will be blocking correct?
Q: I have a project that interacts with SharePoint 2010 object model, so bound to .NET 3.5. Any caveats when using TPL for 3.5?
A: .NET 3.5 is before the TPL was introduced (and well before async/await). There is an AsyncBridge project which attempts to back port the TPL and async support, but I haven’t ever used it.
Q: Can I use Async and await inside a sandboxed CRM Dynamics plugin?
A: I don’t know about Dynamics, sorry. But if they have support for .NET 4.5, I don’t see why not.
Q: How can, for example, the DownloadAsync method be canceled in a proper way from another UI action?
A: Cancellation is done with the CancellationToken/CancellationTokenSource types in .NET. Usually, asynchronous methods just pass the CancellationToken through to whatever APIs they call. For more information, see the MSDN topics “Task-based Asynchronous Pattern” and “Cancellation in Managed Threads”.
Q: How to call an async method from a synchronous method or controller?
Q: Is .NET 4.5.1 the minimum for async / await?
Q: How do we do exception handling inside the DownloadAsync function?
Q: Can you explain how we can perform unit testing using these new keywords?
Q: Is async/await useful for WPF and Windows Form?
A: Yes, async is useful in any UI scenario.
Q: For Task Parallel and async/await which one we should use?
A: The Task Parallel Library is great for CPU-bound code. Async is better for I/O-bound code.
Q: If you got an normal MVC controller that returns a standard view… If that view contains AJAX code to fetch data from an async (WebAPI) controller, would the calling thread be blocked while the AJAX call is running? We have a situation at work where we cant switch page before the AJAX call is done… which seems a bit weird to me.
Q: When building async controllers/methods, is there some way to tell that the code is actually running asynchronous? How can I tell that the code is non blocking?