Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am trying to understand how await async work in C# and one thing is confusing me a lot. I understand that any method that uses await keyword must be marked with async.
My understanding is that when a line with await keyword is hit the code below that line is not executed. An async operation is started to carry on the statement in the await line and the control is returned to the calling method which can proceed with the execution.
Question # 1: Is this assumption correct or the code below the await keyword is still executed?
Secondly suppose I called a service method async and need to return its result. The return statement is below the await keyword.
Question # 2: When is the return statement hit, after the async call has completed or before it?
Question # 3: I want to use the result of that service call and async operation wont help cause I want the calling method to be hit when the result has been returned. I understand this can be done using the Result property which makes the call synchronus. But then what is the use of async in DB operations cause they are the ones that actually take 80% of the time in most apps.
Question # 4: How can I use async with DB operations? Is it possible and recomended?
Question # 5: In which scenraio will async operations be useful it seems that every api is just making async operations now without a reason? or did I miss the point of using async ops?
What I mean by saying that api are making asyn methods without a reason is because methods have to return something and untill that calculation is made how can they return so in essense won't the call be still blocking in sense that it will be useless until result is returned?
MSDN explains everything.
I understand though that sometimes vanilla docs (particularly from MSDN) can be difficult to apply to your particular situation, so let's go over your points.
Question # 1: Is this assumption correct or the code below the await keyword is still executed?
The code below the "await" keyword will only be executed when the async call completes. In the meantime, since your method is marked "async", control will be returned to the caller of your method until your method completes.
From the MSDN link above:
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();
// The await operator suspends AccessTheWebAsync.
// - AccessTheWebAsync can't continue until getStringTask is complete.
// - Meanwhile, control returns to the caller of AccessTheWebAsync.
// - Control resumes here when getStringTask is complete.
// - The await operator then retrieves the string result from getStringTask.
string urlContents = await getStringTask;
I think the comments are quite explanatory.
Secondly suppose I called a service method async and need to return its result. The return statement is below the await keyword.
Question # 2: When is the return statement hit, after the async call has completed or before it?
After.
Question # 3: I want to use the result of that service call and async operation wont help cause I want the calling method to be hit when the result has been returned. I understand this can be done using the Result property which makes the call synchronus. But then what is the use of async in DB operations cause they are the ones that actually take 80% of the time in most apps.
Suppose you need to make three unrelated DB queries to complete your service, then perform a calculation based on the results, then finish. If you did this sequentially, you'd have to wait until each operation completes. If you use async calls, then C# will run the three queries in parallel and your service might finish much sooner.
Also, operations that return Task can be used as Futures. See MSDN on Futures where several patterns are discussed on how to parallelize work based on futures and merge the results.
If your service only needs one DB call then it will definitely be worse for you to call it async.
Question # 4: How can I use async with DB operations? Is it possible and recomended?
ADO.NET now includes async methods ReadAsync and NextResultAsync .
It is definitely possible, as for recommended this discussion is much more complete than I could write here.
Question # 5: In which scenraio will async operations be useful it seems that every api is just making async operations now without a reason? or did I miss the point of using async ops?
async operations are very useful to easily parallelize any long running operations without running into threading problems. If your method only does one thing, or a sequence of simple (fast) things, then yes it is useless to go async. However if you have more than one long running operations, it is far easier and less error prone to parallelize them via async than it is to do it managing threads.
Most of your questions are answered in the official documentation and also in an intro post that I wrote.
Question # 4: How can I use async with DB operations? Is it possible
Entity Framework 6 (currently in Beta) supports async. Lower-level database APIs support asynchronous operations in one way or another. Some of them (e.g., SQLite) support async directly; others need you to write simple async-compatible wrappers.
... and recomended?
Yes, unless you are writing a front-end server (e.g., ASP.NET) that talks to a non-scalable single database machine on the back end. In that specific case, there's no point in making your front end scale because your back end can't scale to match it anyway.
Question # 5: In which scenraio will async operations be useful it seems that every api is just making async operations now without a reason? or did I miss the point of using async ops?
The benefits of asynchronous operations are:
On the client (UI) side, your application remains responsive.
On the server side, your application scales better.
Related
I have read this article:
https://www.compositional-it.com/news-blog/task-vs-async/ that covers the updates in F# 6.
There is a chapter about the introduction of the task expression and its similarity and differences with async.
My understanding is that the task is a block in which we can do async calls, but it is executed in the regular flow, whereas the async block is the one we know, that creates expressions that will be executed later, on demand.
I use async quite extensively since I'm working with an app doing a lot of data streaming and database writing, so everything is pretty much async.
The only use I can see with the task expression is to interface with async api where I want the async block to run right now.
Essentially, replacing:
async {
do! callMyAsyncOnlyApi ()
} |> Async.RunSynchronously
with
task {
do! callMyAsyncOnlyApi ()
}
which would run instantl and release the cpu while waiting.
I must be missing something :D
The article provides an excellent summary in the conclusion section:
Personally, I reach for async {} by default unless I am dealing with external Task based libraries or I face a specific performance issue (which hasn't happened yet!). I find it fits the functional mindset better and is easier to use.
The reality is however that a great deal of libraries have been written with Task in mind, and it is fantastic that F# now has first class, out of the box support for the pattern.
I do not think there is much to add:
F# always had async and async is a reasonable default
There are a number of advantages of async - it supports cancellation and uses the "generator" model which is more composable (and more F# friendly)
.NET uses Task<T> more prominently, so if you are interfacing with a lot of .NET libraries (as your question suggests), then you may choose task
task can be more efficient if you have CPU-bound and not IO-bound code - so in some cases, you may choose that for performance reasons
We use the term "Async" to allow the code stream to continue without blocking the main stream. This is OK. We want the mainstream to continue without waiting for that process to complete. But usually, "Async and Await" are used together.
My question is; When we add "await", we expect "Async" status in the code stream. In this case, I do not understand what is the benefit of using "Async"? Can someone explain this, thank you, good work.
It's not clear which technology you're referring to. I'll assume you're referring to the async and await keywords that have been added to many languages the last few years.
In that case, this statement is actually incorrect:
We use the term "Async" to allow the code stream to continue without blocking the main stream.
In C#, JavaScript, Python, F#, and Visual Basic, the async keyword does not act asynchronously. It has two effects:
Enable the await keyword within that method/lambda.
Transform that method/lambda into a state machine.
So async does not mean "run this code on a background thread" or anything like that, which is a common but incorrect assumption.
The first point above is important for backwards compatibility. Each of these languages use await as a contextual keyword, so the text "await" in a program is only a keyword if it is in a method marked with async. This allows the languages to introduce the new keywords without breaking any existing code (e.g., someone's code that used await as a variable name).
See this post of mine which collected a lot of the discussion around the keywords as they were originally designed for C#/VB. Those same design decisions carried over almost exactly to other languages as they adopted the keywords, too. One of the resources linked from that post is Eric Lippert's post on why we need an async keyword in addition to an await keyword.
Can synchronous and asynchronous functions be integrated into one call/interface whilst maintaining static typing? If possible, can it remain neutral with inheritance, i.e. not wrapping sync methods in async or vice versa (though this might be the best way).
I've been reading around and see it's generally recommending to keep these separate (http://www.tagwith.com/question_61011_pattern-for-writing-synchronous-and-asynchronous-methods-in-libraries-and-keepin and Maintain both synchronous and asynchronous implementations). However, the reason I want to do this is I'm creating a behaviour tree framework for Dart language and am finding it hard to mix both sync and async 'nodes' together to iterate through. It seems these might need to be kept separate, meaning nodes that would suit a sync approach would have to be async, or the opposite, if they are to be within the same 'tree'.
I'm looking for a solution particularly for Dart lang, although I know this is firmly in the territory of general programming concepts. I'm open to this not being able to be achieved, but worth a shot.
Thank you for reading.
You can of course use sync and async functions together. What you can't do is go back to sync execution after a call of an async function.
Maintaining both sync and async methods is in my opinion mostly a waste of time. Sometimes sync versions are convenient to not to have to invoke an async call for some simple operation but in general Dart async is an integral part of Dart. If you want to use Dart you have to get used to it.
With the new async/await feature you can write code that uses async functions almost the same as when only sync functions are used.
As this question is huge, I will give my view on this question so that you can simply tell me whether I am right or not. If not, where to correct. If my view is superficial, please present an overview of F# async usage. In mu understanding, to write async program, you need to put async code into "async" block like async{expression}, and use "let!" or "use!" to bind names to primitives, then you need to use method to run this async expression like "Async.Run". In addition, you can use exception handling to deal with exception, and cancellation to cancel when necessary. I also know there are several primitives that defined in F# core libraries, and F# extension of I/O operation. I just need to make sure the relation between these things. If you think my view on async workflows is superficial, please give an overview usage like what I have mentioned above. Thank you very much!
This question is huge, so at best, I can highlight some ideas and point you to learning resources and examples.
The description in the question isn't wrong (though there is no Async.Run function). But the main point about Asyncs is how they execute and why the way they execute is useful.
An async block defines a piece of code that becomes an Async<'T> object, which can be seen as a computation that can be executed at a later time. The Async returns an object of type 'T when its execution has completed -- if it has neither failed nor been cancelled.
let!, do! and use! are used inside of an async block to run another Async and, in the cases of let! and use!, bind its result to a name inside the current async. Unlike for example normal let, which simply binds any value to a name, the versions with an exclamation mark explicitly "import" the result of another async.
When an Async depends on another and waits for its result, such as with a let! binding, it normally does not block a thread. Asyncs utilize the .NET thread pool for easy parallel execution, and after an Async completes that another Async depends on, a continuation runs the remainder of the dependent Async.
The Async functions offer many ready-made ways to run Asyncs, such as Async.Start, which is a simple dispatch of an Async with no result, Async.RunSynchronously, which runs the Async and returns its result as if it were a normal function, Async.Parallel, which combines a sequence of Asyncs into one that executes them in parallel, or Async.StartAsTask, which runs an Async as an independent task. Further methods allow composition of Asyncs in terms of cancellation, or explicit control over continuation after an exception or cancellation.
Asyncs are very useful where waiting times are included: otherwise blocking calls can use Asyncs to not block execution, for example in I/O bound functions.
The best introductions to F# Asyncs I know are written, or co-written, by Don Syme, the lead designer of F#:
The chapter Reactive, Asynchronous, and Parallel Programming in the book Expert F#
A blog post with examples for asyncronous agents
The blog post introducing Asyncs in late 2007
There is an existing third party Rest API available which would accept one set of input and return the output for the same. (Think of it as Bing's Geo coding service, which would accept address and return location detail)
My need would be is to call this API multiple times (say 500-1000) for a single asp.net request and each call may take close to 500ms to return.
I could think of three approaches on how to do this action. Need your input on which could be best possible approach keeping speed as criteria.
1. Using Http Request in a for loop
Write a simple for loop and for each input call the REST API and add the output to the result. This by far could be the slowest. But there is no overhead of threads or context switching.
2. Using async and await
Use async and await mechanisms to call REST Api. It could be efficient as thread continues to do other activites while waiting for REST call to return. The problem I am facing is that, as per recommendations I should be using await all the way to the top most caller, which is not possible in my case. Not following it may lead to dead locks in asp.net as mentioned here http://msdn.microsoft.com/en-us/magazine/jj991977.aspx
3. Using Task Parallel Library
Using a Parallel.ForEach and use the Synchronuos API to invoke the Server parallely and use ConcurrentDictionary to hold the result. But may result in thread overhead
Also, let me know is there any other better way to handle things. I understand people might suggest to track performance for each approach, but would like to understand how people has solved this problem before
The best solution is to use async and await, but in that case you will have to take it async all the way up the call stack to the controller action.
The for loop keeps it all sequential and synchronous, so it would definitely be the slowest solution. Parallel will block multiple threads per request, which will negatively impact your scalability.
Since the operation is I/O-based (calling a REST API), async is the most natural fit and should provide the best overall system performance of these options.
First, I think it's worth considering some issues that you didn't mention in your question:
500-1000 API calls sounds like quite a lot. Isn't there a way to avoid that? Doesn't the API have some kind of bulk query functionality? Or can't you download their database and query it locally? (The more open organizations like Wikimedia or Stack Exchange often support this, the more closed ones like Microsoft or Google usually don't.)
If those options are not available, then at least consider some kind of caching, if that makes sense for you.
The number of concurrent requests to the same server allowed at the same time in ASP.NET is only 10 by default. If you want to make more concurrent requests, you will need to set ServicePointManager.DefaultConnectionLimit.
Making this many requests could be considered abuse by the service provider and could lead to blocking of your IP. Make sure the provider is okay with this kind of usage.
Now, to your actual question: I think that the best option is to use async-await, even if you can't use it all the way. You can avoid deadlocks either by using ConfigureAwait(false) at every await (which is the correct solution) or by using something like Task.Run(() => /* your async code here */).Wait() to escape the ASP.NET context (which is the simple solution).
Using something like Parallel.ForEach() is not great, because it unnecessarily wastes ThreadPool threads.
If you go with async, you should probably also consider throttling. A simple way to achieve that is by using SemaphoreSlim.