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
, which allows you to complete a task manually. There are some higher-level wrappers
as well, e.g., Task.Factory.FromAsync will take the old Begin/End style asynchronous
methods and wrap them into a task.
Q: Can we use Async inside
LINQ methods (with lambda BLOCKED EXPRESSION?
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.
CodeIt.Right includes extensive Async Best Practices rule set that
will guide you through the intricacies of Async.
Start
a no-cost 14-day trial of CodeIt.Right, SubMain's code quality analysis, automated
code review and refactoring for Visual Studio.
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?
A: Answered
in webinar
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
to create await-compatible wrapper methods. The MSDN docs "Interop with Other Asynchronous
Patterns and Types" under "Task-based Asynchronous Pattern" should get you started.
Q: IAsyncResult fits very
nicely with Windows low level and IOPorts. Does async/await have the same high performance?
A: Answered
in webinar
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?
A: Answered
in webinar
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?
A: Answered
in webinar
Q: Is it acceptable to create
asynchronous versions of synchronous methods by just calling the synchronous methods
with Task.Run
A: Answered
in webinar
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.
CodeIt.Right includes extensive Async Best Practices rule set that
will guide you through the intricacies of Async.
Start
a no-cost 14-day trial of CodeIt.Right, SubMain's code quality analysis, automated
code review and refactoring for Visual Studio.
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.)
A: Answered
in webinar
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?
A: Answered
in webinar
Q: Can you explain the Server
Side Scalability benefit a little more?
A: Answered
in webinar
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?
A: Answered
in webinar
Q: What is the appropriate
way to unit test an async method?
A: Answered
in webinar
Q: The benefit : "Responsiveness
on the client side" sounds like a background process. I thought async wasn't a background
thing...
A: Answered
in webinar
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
IUserStoreMethod(){ // no async stuff, but it requires a Task
, and it cant be changed because it is from the interface. } How should I write the
body? Is Task.Run() inside the method body an exception here?
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?
A: Answered
in webinar
Q: What is the best way to
call Async Methods from class constructors?
A: Answered
in webinar
Q: Shouldn't the Click event
handler be also renamed to ClickAsync?
A: Answered
in webinar
Q: Is it possible to communicate
progress from the async task?
A: Yes. An asynchronous method
can report progress by taking an IProgress
parameter and calling its Report method. UI applications commonly use Progress
as their implementation of IProgress
. There's more information on MSDN under the "Task-based Asynchronous Pattern" topic.
Q: How would unit/integration
test code coverage influence designs and usage of async/await?
A: Answered
in webinar
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?
A: Answered
in webinar
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?
A: Answered
in webinar
Q: Is .NET 4.5.1 the minimum
for async / await?
A: Answered
in webinar
Q: How do we do exception
handling inside the DownloadAsync function?
A: Answered
in webinar
Q: Can you explain how we
can perform unit testing using these new keywords?
A: Answered
in webinar
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.
A: Answered
in webinar
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?
A: Answered
in webinar
CodeIt.Right includes extensive Async Best Practices rule set that
will guide you through the intricacies of Async.
Start
a no-cost 14-day trial of CodeIt.Right, SubMain's code quality analysis, automated
code review and refactoring for Visual Studio.
