Should I use synchronous or asynchronous methods of c# mongodb driver? - c#

In c# mongodb driver, there are both synchronous and asynchronous methods available as shown below?
_mongoCollection.InsertOneAsync(entity);
_mongoCollection.Insert(entity);
I believe, in majority of cases, the amount of work done asynchronously in data access layer is very less. So I am awaiting the database calls immediately as follows:
await _mongoCollection.InsertOneAsync(entity);
await _mongoCollection.DeleteOneAsync(query);
await _mongoCollection.Find(query).ToListAsync();
Now my question is: As i am awaiting the db calls immediately, I am not seeing any use of async methods here. So, should I use async methods? (or) Should i use synchronous methods?

I think the prior answers are missing a major point of asynchrony; namely that when you use the async methods**, you free up the thread you're on while (most of) the I/O operation completes, and it is available for use elsewhere in your app; e.g. servicing other requests.
Let's suppose the Mongo database is on another server. Even with a quick network and quick Mongo instance, that's still perhaps 5ms per command, which on a 2GHz CPU is 10 million clock cycles. While you're not going to get all of those to use on running your code, due to various overheads, you will get still get an advantage if you have an app that can use the additional threads productively.
So if your app is for instance a website, API, or UI, I would use the async methods. If it's a single thread console app, you probably won't gain any of the above benefit.
--
** This assumes the Mongo async method are truly async, and not just wrappers for the sync methods.

that depends on if you have any use of result in next statement or not.
for e.g.
void async myMethod(){
var result = funcAsync();
// do some additional work..
var data = await result;
.
.
}
above is scenario where you should use async await.
Now let assume if you have method;
void async myMethod(){
var result = await funcAsync(); // here result is required before any other logic ahead
.
.
.
}
here you really don't need to use async await, but what if in near future your system changed and you need to add additional code in between, then you might need to change method signatures and corresponding location where that method is called.
So this is totally depends on the requirement.

It really depends on what are your requirements.
From the code you've posted I can guess that you don't need an asynchronous call but it may come in handy with the last call _mongoCollection.Find(...).ToListAsync()
Asynchronous calls ( IMHO ) should be used only when you have some independent/complex logic. In example that you showed I think you can only await the last call making it :
_mongoCollection.Insert(entity);
_mongoCollection.Find(query).ToListAsync();
This way you can simply do some extra logic while awaiting ToListAsync() :
_mongoCollection.Insert(entity);
Task<List<object>> _task = _mongoCollection.Find(query).ToListAsync();
// my complex logic/calculations and stuff
await _task;
Being 100% honest I don't see any other reason to use asynchronous calls.
My opiniion is that from your example, usage of asynchronous call is just useless.

Related

In .NET, are async methods exclusively those with the async keyword?

I've been learning about HttpClient (consuming API's in .NET in general), and therefore about async programming. I'm still pretty lost right now, so trying to clear some things up. One question I can't seem to find an answer to - are asynchronous methods implemented exclusively using the async keyword?
I understand that you could (theoretically) create synchronous methods using async programming, but how do you recognize that? For example, from this link and this example:
public string GetReleases(string url)
{
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add(RequestConstants.UserAgent, RequestConstants.UserAgentValue);
var response = httpClient.GetStringAsync(new Uri(url)).Result;
return response;
}
}
The author says:
For the simplicity’s sake, I implemented it synchronously
But how do I recognize it is synchronous? Is it solely because the method is not defined with async Task, for example:
public async Task<string> GetReleases(string url)
Does that mean that in this HttpClient tutorial, this example is also not asynchronous:
// GET: Student
public ActionResult Index()
{
IEnumerable<StudentViewModel> students = null;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:64189/api/");
//HTTP GET
var responseTask = client.GetAsync("student");
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync<IList<StudentViewModel>>();
readTask.Wait();
students = readTask.Result;
}
else //web api sent error response
{
//log response status here..
students = Enumerable.Empty<StudentViewModel>();
ModelState.AddModelError(string.Empty, "Server error. Please contact administrator.");
}
}
return View(students);
}
So to sum up, my questions are:
Is async programming (in .NET), and async methods, implemented exclusively using async and void/Task/Task?
If not, how else, and if so, how do I recognize "true" asynchronous methods compared to synchronous methods implemented using asychronous principles (like the example above?)
Why then did the above examples use "sync through async", since from everything I've read everyone says to NEVER do that? Are they just bad examples, or for simplicity sake (even so, shouldn't "the correct way" > "simplicity"? Would it be ok to use this in situations where, e.g., I have very simple code and want to avoid threading/deadlock issues, since I'm not comfortable with async programming just yet?
how can I recognize truely async/sync methods?
You can't. Not really. You can spot methods that are potentially async, but little else can be learned without consulting documentation or the implementation of those methods.
So, you can examine a method's return type. If it's void, you don't know much. If it's Task, Task<T>, ValueTask<T> or any other awaitable type1, then the method may be asynchronous. But bear in mind, the method signature may be fixed because the type inherited the method from a base class or it's implementing an interface; So whilst the method has the potential to be async, the actual implementation of that method may be completely synchronous.
Or, the method may have the potential to be asynchronous but may have particular control flows which lead to it behaving synchronously2. These may be e.g. that if certain conditions are true, the method already has the answer, so it returns it straight away. Otherwise it goes off and does something async - as one example.
If the return type isn't awaitable and it's non-void, all you can actually reason about the method is that, at the point at which it returns, it's supplied some value for that return type3. There's no way to reason about any other work that may have been started by that method - only that if it's done something like that, it doesn't intend for you to be able to discover when that work has completed.
If you're looking at the implementation of a method and asking yourself "is this implementation async" then the important thing is to work out what this code makes happen after control is returned back to the caller.
When is control returned back to the caller?
When we hit a return
When we hit an await, maybe
When we hit an await, we only return control back to the caller4 if the awaitable that we're awaiting isn't complete yet. So we have to find out where that awaitable came from and, if it came from calling another method, we have to start again from scratch in considering what that method does.
If the method contains awaits then it's usually safest to say that it's potentially async - but bear in mind the above possibilities about already completed awaitables and early returns.
If it's not async/await, what else might it have done? Well, if it's working with Tasks, it may have created one or more of those tasks to represent it's ongoing work. It may have scheduled more code to run via ContinueWith.
If it's not working with Tasks directly, hasn't called something else that is potentially async, hasn't cause a new Thread to be created and isn't needlessly obfuscated, it's probably synchronous.
Would it be ok to use this in situations where, e.g., I have very simple code and want to avoid threading/deadlock issues, since I'm not comfortable with async programming just yet?
The sync over async patterns shown in the examples in your question are more prone to deadlocks than working with async/await. Why? Because they block the current thread waiting for other things to happen. But the current thread or resources that it has locked may be special - and the actual async tasks that it's invoked may need to gain access to that same thread/resource before they can complete. Classic deadlock.
1Awaitable is one of a number of places where C# uses "duck typing". If there's a method available (instance or extension) called GetAwaiter that returns a type with the right shape, it's awaitable. So despite the fact that you'll probably never see one, be aware that custom awaitables are possible in the language.
2"Hot path" optimizations come to mind.
3And out/ref parameters. Of course, if it has those it won't be an async method implemented via the async/await keywords but it may still have some asynchronous behaviour.
4If we've already yielded control back to the caller during an earlier await, we won't return control back to the caller at later awaits, but we'll be returning it to "something" that isn't our code.
If a method returns a Task or Task<T> (with exception to void in case of event handler) then it can be awaited and hence it can be asynchronous. async keyword is only an indication that it may await somewhere for another awaitable. Based on the control flow, async may return without actually awaiting anything.
Asynchronous programming is not a new thing, it has existed in many forms like callbacks, Invokes etc.
Examples you have provided are not using async await pattern properly. Microsoft has provided naming convention (Async Suffix) and Task<T>, Task as types for async programming. So if you see some method returning Task<T> or Task and Method name has suffix "Async" then you can consider it asynchronous. Although suffix thing is not required by compiler, it helps in differentiating it from its synchronous counterpart. (Read vs ReadAsync)
They are bad examples, those action should be marked as async and all the Async methods should be awaited for result. There can be an exception in some console program where main can't be async.
Please read Stephen Cleary blog on async await
An asynchronous method in C# can return void, Task or Task<T>, where void should be avoided in general because it cannot be awaited.
As a convention asynchronous methods should be called DoSomethingAsync()
The async keyword, however, is an implementation detail and does not belong to the API. This keyword is only required if you use an await in the method body. But that need not be the case. You could simply delegate to another asynchronous method, without the need to mark the method as async and using an await.
So 'true' asynchronous methods should be recognizable by the Async suffix of the method name, however, you can't be sure the implementor actually uses naturally asynchronous operations or even runs synchronously some parts or the whole method.
In the example he made the method synchronously by putting .Result at the end of GetStringAsync

Fire and forget without async void

I have three methods where the first result will be used in the next two methods and no data expected to be return back.
result= await DataAccess.Query(param); //Query
await DataAccess.Create(result);
await DataAccess.Update(result);
Do I really need to use await here?
is it correct to use async void
in create and update function?
what will be the right approach to do
a fire and forget here?
if Im not mentioning async will it be fire
and forget?
what is the significance of async without await if it
only used to run synchronously? I can even achieve that without that keyword.
no data expected to be return back.
What about errors? Do you need to return an error code if an error occurs, or is 200 OK acceptable even if the Create or Update fails?
I'm assuming you'll need an error code. 99.99% of calls do.
Do I really need to use await here?
Well, if you want synchronous methods, then you can just call synchronous APIs. I don't know why you would want that, though.
As a reminder: await has nothing to do with returning to the browser. It has everything to do with using fewer thread pool threads, allowing your server to scale further.
is it correct to use async void in create and update function?
No. Never.
what will be the right approach to do a fire and forget here?
The correct approach is "don't". Fire-and-forget is difficult to do correctly, and in fact since you need an error code, you can't do fire-and-forget.
I write more about fire-and-forget - including why StartNew and Task.Run are invalid solutions - on my blog. Note that the only fully reliable solution (including upgrade scenarios) is the last one (distributed architecture).
what is the significance of async without await if it only used to run synchronously? I can even achieve that without that keyword.
It's running serially (in order), not synchronously (blocking a thread). The benefit of async is to allow greater scalability. For more information, see my intro to async on ASP.NET article.
If you need to call several methods in specific order, but this whole set of functions can run asynchronously, I would do:
Task.Run(() =>
{
result = Function();
Create(result);
Update(result);
});
This will separate group of functions into new thread. Since you are not awaiting this task, it is fire and forget.
If your functions are defined as async, you can wait for them to finish like this:
Task.Run(() =>
{
var task = Function();
task.Wait();
var result = task.Result;
Create(result).Wait();
Update(result).Wait();
});
But when you are not going to benefit from async methods, it will be better to override your methods to run synchronously and use the first code

When to use "async" instead of returning a new Task.Run task?

So here I have a function
static bool Login(SignupData sd)
{
bool success=false;
/*
Perform login-related actions here
*/
}
And there is another function
static Task<bool> LoginAsync(SignupData sd)
{
return Task.Run<bool>(()=>Login(sd));
}
Now, I've come across a rather different implementation of this pattern, where you would add the async keyword to a function which returns Task<TResult> (so that it ends up looking like: async Task<TResult> LoginAsync(SignupData sd)). In this case, even if you return TResult instead of a Task<TResult>, the program still compiles.
My question here is, which implementation should be prefered?
static Task<bool> LoginAsync(SignupData sd)
{
return Task.Run<bool>(()=>Login(sd));
}
OR this one?
async static Task<bool> LoginAsync(SignupData sd)
{
bool success=Login(sd);
return success;
}
You shouldn't be doing either. Asynchronous methods are useful if they can prevent threads from being blocked. In your case, your method doesn't avoid that, it always blocks a thread.
How to handle long blocking calls depends on the application. For UI applications, you want to use Task.Run to make sure you don't block the UI thread. For e.g. web applications, you don't want to use Task.Run, you want to just use the thread you've got already to prevent two threads from being used where one suffices.
Your asynchronous method cannot reliably know what works best for the caller, so shouldn't indicate through its API that it knows best. You should just have your synchronous method and let the caller decide.
That said, I would recommend looking for a way to create a LoginAsync implementation that's really asynchronous. If it loads data from a database, for instance, open the connection using OpenAsync, retrieve data using ExecuteReaderAsync. If it connects to a web service, connect using the asynchronous methods for whatever protocol you're using. If it logs in some other way, do whatever you need to make that asynchronous.
If you're taking that approach, the async and await keywords make perfect sense and can make such an implementation very easy to create.
While HVD is correct, I will dive into async in an attempt to describe its intended use.
The async keyword, and the accompanying await keyword is a shortcut method of implementing non blocking code patterns within your application. While it plays along perfectly with the rest of the Task Parallel Library (TPL), it isn't usually used quite the same. It's beauty is in the elegance of how the compiler weaves in the asynchronicity, and allows it to be handled without explicitly spinning off separate threads, which may or may not be what you want.
For Example, let's look at some code:
async static Task<bool> DoStuffAsync()
{
var otherAsyncResult = doOtherStuffAsync();
return await otherAsyncResult
}
See the await keyword? It says, return to the caller, continue on until we have the result you need. Don't block, don't use a new thread, but basically return with a promise of a result when ready (A Task). The calling code can then carry on and not worry about the result until later when we have it.
Usually this ends up requiring that your code becomes non-blocking the whole way down (async all the way as it were), and often this is a difficult transition to understand. However, if you can it is incredibly powerful.
The better way to handle your code would be to make the synchronous code call the async one, and wait on it. That way you would be async as much as possible. It is always best to force that level as high as possible in your application, all the way to the UI if possible.
Hope that made sense. The TPL is a huge topic, and Async/Await really adds some interesting ways of structuring your code.
https://msdn.microsoft.com/en-us/library/hh191443.aspx

async and await without "threads"? Can I customize what happens under-the-hood?

I have a question about how customizable the new async/await keywords and the Task class in C# 4.5 are.
First some background for understanding my problem: I am developing on a framework with the following design:
One thread has a list of "current things to do" (usually around 100 to 200 items) which are stored as an own data structure and hold as a list. It has an Update() function that enumerates the list and look whether some "things" need to execute and does so. Basically its like a big thread sheduler. To simplify things, lets assume the "things to do" are functions that return the boolean true when they are "finished" (and should not be called next Update) and false when the sheduler should call them again next update.
All the "things" must not run concurrently and also must run in this one thread (because of thread static variables)
There are other threads which do other stuff. They are structured in the same way: Big loop that iterates a couple of hundret things to do in a big Update() - function.
Threads can send each other messages, including "remote procedure calls". For these remote calls, the RPC system is returning some kind of future object to the result value. In the other thread, a new "thing to do" is inserted.
A common "thing" to do are just sequences of RPCs chained together. At the moment, the syntax for this "chaining" is very verbose and complicated, since you manually have to check for the completion state of previous RPCs and invoke the next ones etc..
An example:
Future f1, f2;
bool SomeThingToDo() // returns true when "finished"
{
if (f1 == null)
f1 = Remote1.CallF1();
else if (f1.IsComplete && f2 == null)
f2 = Remote2.CallF2();
else if (f2 != null && f2.IsComplete)
return true;
return false;
}
Now this all sound awefull like async and await of C# 5.0 can help me here. I haven't 100% fully understand what it does under the hood (any good references?), but as I get it from some few talks I've watched, it exactly does what I want with this nicely simple code:
async Task SomeThingToDo() // returning task is completed when this is finished.
{
await Remote1.CallF1();
await Remote2.CallF2();
}
But I can't find a way how write my Update() function to make something like this happen. async and await seem to want to use the Task - class which in turn seems to need real threads?
My closest "solution" so far:
The first thread (which is running SomeThingToDo) calls their functions only once and stores the returned task and tests on every Update() whether the task is completed.
Remote1.CallF1 returns a new Task with an empty Action as constructor parameter and remembers the returned task. When F1 is actually finished, it calls RunSynchronously() on the task to mark it as completed.
That seems to me like a pervertion of the task system. And beside, it creates shared memory (the Task's IsComplete boolean) between the two threads which I would like to have replaced with our remote messanging system, if possible.
Finally, it does not solve my problem as it does not work with the await-like SomeThingToDo implementation above. It seems the auto-generated Task objects returned by an async function are completed immediately?
So finally my questions:
Can I hook into async/await to use my own implementations instead of Task<T>?
If that's not possible, can I use Task without anything that relates to "blocking" and "threads"?
Any good reference what exactly happens when I write async and await?
I haven't 100% fully understand what it does under the hood - any good references?
Back when we were designing the feature Mads, Stephen and I wrote some articles at a variety of different levels for MSDN magazine. The links are here:
http://blogs.msdn.com/b/ericlippert/archive/2011/10/03/async-articles.aspx
Start with my article, then Mads's, then Stephen's.
It seems the auto-generated Task objects returned by an async function are completed immediately?
No, they are completed when the code in the method body returns or throws, same as any other code.
Can I hook into async/await to use my own implementations instead of Task<T>?
A method which contains an await must return void, Task or Task<T>. However, the expression that is awaited can return any type so long as you can call GetAwaiter() on it. That need not be a Task.
If that's not possible, can I use Task without anything that relates to "blocking" and "threads"?
Absolutely. A Task just represents work that will complete in the future. Though that work is typically done on another thread, there is no requirement.
To answer your questions:
Can I hook into async/await to use my own implementations instead of Task?
Yes. You can await anything. However, I do not recommend this.
If that's not possible, can I use Task without anything that relates to "blocking" and "threads"?
The Task type represents a future. It does not necessarily "run" on a thread; it can represent the completion of a download, or a timer expiring, etc.
Any good reference what exactly happens when I write async and await?
If you mean as far as code transformations go, this blog post has a nice side-by-side. It's not 100% accurate in its details, but it's enough to write a simple custom awaiter.
If you really want to twist async to do your bidding, Jon Skeet's eduasync series is the best resource. However, I seriously do not recommend you do this in production.
You may find my async/await intro helpful as an introduction to the async concepts and recommended ways to use them. The official MSDN documentation is also unusually good.
I did write the AsyncContext and AsyncContextThread classes that may work for your situation; they define a single-threaded context for async/await methods. You can queue work (or send messages) to an AsyncContextThread by using its Factory property.
Can I hook into async/await to use my own implementations instead of Task?
Yes.
If that's not possible, can I use Task without anything that relates to "blocking" and "threads"?
Yes.
Any good reference what exactly happens when I write async and await?
Yes.
I would discourage you from asking yes/no questions. You probably don't just want yes/no answers.
async and await seem to want to use the Task - class which in turn seems to need real threads?
Nope, that's not true. A Task represents something that can be completed at some point in the future, possibly with a result. It's sometimes the result of some computation in another thread, but it doesn't need to be. It can be anything that is happening at some point in the future. For example, it could be the result of an IO operation.
Remote1.CallF1 returns a new Task with an empty Action as constructor parameter and remembers the returned task. When F1 is actually finished, it calls RunSynchronously() on the task to mark it as completed.
So what you're missing here is the TaskCompletionSource class. With that missing puzzle piece a lot should fit into place. You can create the TCS object, pass the Task from it's Task property around to...whomever, and then use the SetResult property to signal it's completion. Doing this doesn't result in the creation of any additional threads, or use the thread pool.
Note that if you don't have a result and just want a Task instead of a Task<T> then just use a TaskCompletionSource<bool> or something along those lines and then SetResult(false) or whatever is appropriate. By casting the Task<bool> to a Task you can hide that implementation from the public API.
That should also provide the "How" variations of the first two questions that you asked instead of the "can I" versions you asked. You can use a TaskCompletionSource to generate a task that is completed whenever you say it is, using whatever asynchronous construct you want, which may or may not involve the use of additional threads.

When to run an async function concurrently?

The async-await features make it elegant to write non-blocking code. But, while non blocking, the work performed within an async function can still be non-trivial.
When writing async code, I find it natural to write code that follows the pattern 'all the way down the rabbit hole', so to speak, where all methods within the calling tree are marked async and the APIs used are async; but even while non blocking, the executed code can take up a fair amount of the contextual thread's time.
How and when do you decide to run an async-able method concurrently on top of asynchronously? Should one err on having the new Task created higher or lower in the call tree? Are there any best practices for this type of 'optimization'?
I've been using async in production for a couple of years. There are a few core "best practices" that I recommend:
Don't block on async code. Use async "all the way down". (Corollary: prefer async Task to async void unless you have to use async void).
Use ConfigureAwait(false) wherever possible in your "library" methods.
You've already figured out the "async all the way down" part, and you're at the point that ConfigureAwait(false) becomes useful.
Say you have an async method A that calls another async method B. A updates the UI with the results of B, but B doesn't depend on the UI. So we have:
async Task A()
{
var result = await B();
myUIElement.Text = result;
}
async Task<string> B()
{
var rawString = await SomeOtherStuff();
var result = DoProcessingOnRawString(rawString);
return result;
}
In this example, I would call B a "library" method since it doesn't really need to run in the UI context. Right now, B does run in the UI thread, so DoProcessingOnRawString is causing responsiveness issues.
So, add a ConfigureAwait(false) to every await in B:
async Task<string> B()
{
var rawString = await SomeOtherStuff().ConfigureAwait(false);
var result = DoProcessingOnRawString(rawString);
return result;
}
Now, when B resumes after awaiting SomeOtherStuff (assuming it did actually have to await), it will resume on a thread pool thread instead of the UI context. When B completes, even though it's running on the thread pool, A will resume on the UI context.
You can't add ConfigureAwait(false) to A because A depends on the UI context.
You also have the option of explicitly queueing tasks to the thread pool (await Task.Run(..)), and you should do this if you have particular CPU-intensive functionality. But if your performance is suffering from "thousands of paper cuts", you can use ConfigureAwait(false) to offload a lot of the async "housekeeping" onto the thread pool.
You may find my intro post helpful (it goes into more of the "why's"), and the async FAQ also has lots of great references.
Async-await does not actually use threads in the current .NET process-space. it is designed for "blocking" IO and network operations, like database calls, web requests, some file IO.
I cannot perceive what advantage there would be in C# to what you call the rabbit-hole technique. Doing so only obscures the code and unnecessarily couples your potentially high-cpu code to your IO code.
To answer your question directly, I would only use async-await for the aforementioned IO/network scenarios, right at the point where you are doing the blocking operations, and for anything that was CPU bound I would use threading techniques to make the best use of the available CPU cores. No need to mix the two concerns.

Categories

Resources