c# synch and asynch calls on blob upload and wait function - c#

I am trying to understand the difference between these lines of code. I have an object of memorystream called arContents and works fine when its size is small. I see the file upload.
blockBlob.UploadFromStreamAsync(arContents)
But when the memorystream is large, the above code runs without errors but uploads no file. However when I added the WAIT() function call, this worked.
blockBlob.UploadFromStreamAsync(arContents).Wait();
I would like to understand first of all What is wait call doing and why is it an async call. Guess want to know the difference between asynch and synch calls too.
Also, I have seen the await also.. code like this
await blockBlob.UploadFromStreamAsync(arContents)
What is the difference?
Thanks

I see you tagged multithreading on your question, so I think it is important to note that asynchronous and multi-threading are two completely different things. Read through Microsoft's article called The Task asynchronous programming model in C# for a good explanation of how they are different. The example about cooking really helps make this point clear.
When you call an asynchronous method, the task (whatever that is) will start. But you usually also want to either:
Know that it finished successfully, or
Use the returned result from the task (like, if it was retrieving data)
How and when you do that is when things get interesting. The point of asynchronous programming is to allow the thread to go and do something else while waiting for something else to happen (a network request, data from the hard drive, etc) rather than the thread just sitting idle until the task completes.
You have probably experienced some programs that completely lock up and don't let you do anything while it's doing something. That is what asynchronous programming allows you to avoid.
In your first example, you aren't waiting for the result at all. That's often called "fire and forget". You start the task, then code execution immediately moves on to the next line and you will never know if the task completed successfully.
Using .Wait() is not asynchronous at all. It will lock up the thread until the task finishes. Worse than that, when you try to force an asynchronous method to be synchronous, it can sometimes cause a deadlock that your application cannot recover from. Search for c# async wait deadlock and you'll find many examples and explanations.
Ideally, you will want to use await. This is what happens when you use it:
The method (UploadFromStreamAsync) is called.
When an asynchronous operation starts, UploadFromStreamAsync returns a Task.
The await keyword will look at the Task, and if it is not complete, it will put the rest of the current method on the "to do" list for when the Task does finish and return a new Task to the calling method.
As long as you have used async all the way up the call stack, then at that point, the thread can go and do something else it has on its "to do" list. In ASP.NET it could be working on a new request that came in. In a desktop app it could be responding to user input. That would happen on the same thread.
Whenever that task finishes, then await extracts the returned value from the Task. If the method returned just a Task, then that is similar to void (no return value). If it is Task<T>, then it will return the object of type T. Then your code resumes execution after the await line.
That all sounds complicated, but you don't really need to understand completely what it's doing, and that's by design. This feature of C# lets you use asynchronous programming in a way that looks very similar to normal synchronous programming. For example:
public async Task Upload() {
...
await blockBlob.UploadFromStreamAsync(arContents);
}
Will do exactly the same as this:
public void Upload() {
...
blockBlob.UploadFromStream(arContents);
}
They look very similar, except that using async/await will give you the benefits I talked about above and the second will not.

Related

How do I force a wait in the C# async await model

I think I must be missing something with my understanding of the async await model. What should be a simple thing seems to be unbelievably hard to achieve.
I have a UI which needs to check if the user is logged in. To do this I need to call a method in one of my classes which does some queries.
This class in turn calls 3rd party code which only has async methods.
How can I call that async method and make the application wait until I get a result?
I have tried all the things suggested such as ConfigureAwait, RunSynchronous, .Result, etc.. Nothing seems to reliably work.
It seems so stupid that something like this is so difficult so I assume I am missing a key piece of information.
Thanks.
Lets make something clear:
"make the application wait until I get a result?"
Has nothing to do (I cannot stress this enough) with blocking, awaiting or any result whatsoever.
If you are used of making the UI lock until something is done, you should switch your design, instead of trying to find a way to accomplish it.
(I have spent fair amount of time writing MFC apps for Windows Mobile, I used to do this as well)
The correct way to handle such situation, is to let the user know, that there is work being done (Some sort of Activity Indicator for example), and at the same time, make sure that no other code can be executed due to User Input (CanExecute property of your Command for example). When it is appropriate, you can put Cancelation logic.
Even more, in the context of MAUI (and mobile development in general), blocking the UI thread, even for few seconds, is totally not acceptable. It should remain responsive at all times. This is not a matter of choice.
You can use the Task.Result in the property to block the calling thread until the Task is completed. However, this is not recommended in most cases because it can lead to deadlocks. A better approach is to use await in a method marked as async, which will cause the method to return control to the calling method until the awaited Task is completed. If you need to block the thread, consider using ConfigureAwait(false) when awaiting the Task.
Read this for further information about the synchronous error handling to Async / Callback programs.

If I'm going to use the result from await immediately, do I get any benefit from async?

Consider the code in this example:
https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client
In several places they have code that looks like this:
if (response.IsSuccessStatusCode)
{
product = await response.Content.ReadAsAsync<Product>();
}
return product;
The way I see it, if there is no independent code following the await, then there is little benefit to using async. (I know that there are many API's that are *AsAsync() only, so in those cases I don't have a choice.)
Or am I missing something? Is there a benefit for going all async, all the time?
Yes there is benefit as we are not blocking caller on the operation that we are doing which is not the case for sync calls.
Think of it was called in windows form application as synchrounous call then on a button click suppose, then the app would be unresponsive and user wouldn't be able to do any operation until the call to Web API method complete s either with success or failure which we don't want nowadays in many cases I.e keep the application responsive for better UX.
The basic purpose is to simplify the old way of using background worker class to do long running operations or I/O bound operations. The asynchronous execution will cause not to block the caller code and resume from where it left when the result is returned back from the operation.
So in the above case calling a Web API method involves network latency and it could take more than normal time and if we are not calling it asynchronously we have blocked the calling code or thread until the result is returned.
Update:
To clarify Calling async method without await wouldnt block but your control would flow through and you won't be able to access the result while await would keep that context, without await you will have to wait for it to complete and block it like Async().Result which ofcoruse means calling async method synchronously.
Hope it helps

In "truly asynchronous" code that uses async-await, isn't there still SOME "thread" that is stuck waiting?

Let's say I properly use async-await, like
await client.GetStringAsync("http://stackoverflow.com");
I understand that the thread that invokes the await becomes "free", that is, something further up the call chain isn't stuck executing some loop equivalent to
bool done = false;
string html = null;
for(; !done; done = GetStringIfAvailable(ref html));
which is what it would be doing if I called the synchronous version of GetStringAsync (probably called GetString by convention).
However, here's where I get confused. Even if the calling thread or any other thread in application's pool of available threads isn't blocked with such a loop, then something is, because, as I understand, at a low level there is always polling going on. So, instead of lowering the total amount of work, I'm simply pushing work to something "beneath" my application's threads ... or something like that.
Can someone clear this up for me?
No.
The compiler will convert methods that use async / await in to state machines that can be broken up in to multiple steps. Once an await is hit, the state of the method is stored and execution is "offloaded" back to the thread that called it. If the task is waiting on things like disk IO, the OS kernel will end up relying on physical CPU interrupts to let the kernel know when to signal the application to resume processing. The state of the pending method is loaded, and queued up on an available thread (the same thread that hit the await if ConfigureAwait is true, or any free thread if false) (This last part isn't exactly right, please see Scott Chamberlain's comments below.). Think of it like an event, where the application asks the hardware to "ping" it once the work is done, while the application gets back to doing whatever it was doing before.
There are some cases where a new thread is spun up to do the work, such as Task.Run which does the work on a ThreadPool thread, but no thread is blocking while awaiting it to complete.
It is important to keep in mind that asynchronous operations using async/ await, are all about pausing, storing, retrieving, and resuming that state-machine. It doesn't really care about what happens inside the Task, what happens there, and how it happens, isn't directly related to async / await.
I was very confused by async / await too, until I really understood how the method is converted to a state-machine. Reading up on exactly what your async methods get converted to by the compiler might help.
You're pushing it off onto the operating system--which will run some other thread if it can rather than simply wait. It only ends up in a busy-wait when it can't find any thread that wants to run.

Web API Sync Calls Best Practice

Probably this question has already been made, but I never found a definitive answer. Let's say that I have a Web API 2.0 Application hosted on IIS. I think I understand that best practice (to prevent deadlocks on client) is always use async methods from the GUI event to the HttpClient calls. And this is good and it works. But what is the best practice in case I had client application that does not have a GUI (e.g. Window Service, Console Application) but only synchronous methods from which to make the call? In this case, I use the following logic:
void MySyncMethodOnMyWindowServiceApp()
{
list = GetDataAsync().Result().ToObject<List<MyClass>>();
}
async Task<Jarray> GetDataAsync()
{
list = await Client.GetAsync(<...>).ConfigureAwait(false);
return await response.Content.ReadAsAsync<JArray>().ConfigureAwait(false);
}
But unfortunately this can still cause deadlocks on client that occur at random times on random machines.
The client app stops at this point and never returns:
list = await Client.GetAsync(<...>).ConfigureAwait(false);
If it's something that can be run in the background and isn't forced to be synchronous, try wrapping the code (that calls the async method) in a Task.Run(). I'm not sure that'll solve a "deadlock" problem (if it's something out of sync, that's another issue), but if you want to benefit from async/await, if you don't have async all the way down, I'm not sure there's a benefit unless you run it in a background thread. I had a case where adding Task.Run() in a few places (in my case, from an MVC controller which I changed to be async) and calling async methods not only improved performance slightly, but it improved reliability (not sure that it was a "deadlock" but seemed like something similar) under heavier load.
You will find that using Task.Run() is regarded by some as a bad way to do it, but I really couldn't see a better way to do it in my situation, and it really did seem to be an improvement. Perhaps this is one of those things where there's the ideal way to do it vs. the way to make it work in the imperfect situation that you're in. :-)
[Updated due to requests for code]
So, as someone else posted, you should do "async all the way down". In my case, my data wasn't async, but my UI was. So, I went async down as far as I could, then I wrapped my data calls with Task.Run in such as way that it made sense. That's the trick, I think, to figure out if it makes sense that things can run in parallel, otherwise, you're just being synchronous (if you use async and immediately resolve it, forcing it to wait for the answer). I had a number of reads that I could perform in parallel.
In the above example, I think you have to async up as far as makes sense, and then at some point, determine where you can spin off a t hread and perform the operation independent of the other code. Let's say you have an operation that saves data, but you don't really need to wait for a response -- you're saving it and you're done. The only thing you might have to watch out for is not to close the program without waiting for that thread/task to finish. Where it makes sense in your code is up to you.
Syntax is pretty easy. I took existing code, changed the controller to an async returning a Task of my class that was formerly being returned.
var myTask = Task.Run(() =>
{
//...some code that can run independently.... In my case, loading data
});
// ...other code that can run at the same time as the above....
await Task.WhenAll(myTask, otherTask);
//..or...
await myTask;
//At this point, the result is available from the task
myDataValue = myTask.Result;
See MSDN for probably better examples:
https://msdn.microsoft.com/en-us/library/hh195051(v=vs.110).aspx
[Update 2, more relevant for the original question]
Let's say that your data read is an async method.
private async Task<MyClass> Read()
You can call it, save the task, and await on it when ready:
var runTask = Read();
//... do other code that can run in parallel
await runTask;
So, for this purpose, calling async code, which is what the original poster is requesting, I don't think you need Task.Run(), although I don't think you can use "await" unless you're an async method -- you'll need an alternate syntax for Wait.
The trick is that without having some code to run in parallel, there's little point in it, so thinking about multi-threading is still the point.
Using Task<T>.Result is the equivalent of Wait which will perform a synchronous block on the thread. Having async methods on the WebApi and then having all the callers synchronously blocking them effectively makes the WebApi method synchronous. Under load you will deadlock if the number of simultaneous Waits exceeds the server/app thread pool.
So remember the rule of thumb "async all the way down". You want the long running task (getting a collection of List) to be async. If the calling method must be sync you want to make that conversion from async to sync (using either Result or Wait) as close to the "ground" as possible. Keep they long running process async and have the sync portion as short as possible. That will greatly reduce the length of time that threads are blocked.
So for example you can do something like this.
void MySyncMethodOnMyWindowServiceApp()
{
List<MyClass> myClasses = GetMyClassCollectionAsync().Result;
}
Task<List<MyClass>> GetMyListCollectionAsync()
{
var data = await GetDataAsync(); // <- long running call to remote WebApi?
return data.ToObject<List<MyClass>>();
}
The key part is the long running task remains async and not blocked because await is used.
Also don't confuse the responsiveness with scalability. Both are valid reasons for async. Yes responsiveness is a reason for using async (to avoid blocking on the UI thread). You are correct this wouldn't apply to a back end service however this isn't why async is used on a WebApi. The WebApi is also a non GUI back end process. If the only advantage of async code was responsiveness of the UI layer then WebApi would be sync code from start to finish. The other reason for using async is scalability (avoiding deadlocks) and this is the reason why WebApi calls are plumbed async. Keeping the long running processes async helps IIS make more efficient use of a limited number of threads. By default there are only 12 worker threads per core. This can be raised but that isn't a magic bullet either as threads are relatively expensive (about 1MB overhead per thread). await allows you to do more with less. More concurrent long running processes on less threads before a deadlock occurs.
The problem you are having with deadlocks must stem from something else. Your use of ConfigureAwait(false) prevents deadlocks here. Solve the bug and you are fine.
See Should we switch to use async I/O by default? to which the answer is "no". You should decide on a case by case basis and choose async when the benefits outweigh the costs. It is important to understand that async IO has a productivity cost associated with it. In non-GUI scenarios only a few targeted scenarios derive any benefit at all from async IO. The benefits can be enormous, though, but only in those cases.
Here's another helpful post: https://stackoverflow.com/a/25087273/122718

Asynchronous DB-Query to trigger Stored Procedure

I want to performa an asynchronous DB Query in C# that calls a stored procedure for a Backup. Since we use Azure this takes about 2 minutes and we don't want the user to wait that long.
So the idea is to make it asynchronous, so that the task continues to run, after the request.
[HttpPost]
public ActionResult Create(Snapshot snapshot)
{
db.Database.CommandTimeout = 7200;
Task.Run(() => db.Database.ExecuteSqlCommandAsync("EXEC PerformSnapshot #User = '" + CurrentUser.AccountName + "', #Comment = '" + snapshot.Comment + "';"));
this.ShowUserMessage("Your snapshot has been created.");
return this.RedirectToActionImpl("Index", "Snapshots", new System.Web.Routing.RouteValueDictionary());
}
I'm afraid that I haven't understood the concept of asynchronous taks. The query will not be executed (or aborted?), if I don't use the wait statement. But actually "waiting" is the one thing I espacially don't want to do here.
So... why am I forced to use wait here?
Or will the method be started, but killed if the requst is finished?
We don't want the user to wait that long.
async-await won't help you with that. Odd as it may sound, the basic async-await pattern is about implementing synchronous behavior in a non-blocking fashion. It doesn't re-arrange your logical flow; in fact, it goes to great lengths to preserve it. The only thing you've changed by going async here is that you're no longer tying up a thread during that 2-minute database operation, which is a huge win your app's scalability if you have lots of concurrent users, but doesn't speed up an individual request one bit.
I think what you really want is to run the operation as a background job so you can respond to the user immediately. But be careful - there are bad ways to do that in ASP.NET (i.e. Task.Run) and there are good ways.
Dave, you're not forced to use await here. And you're right - from user perspective it still will take 2 minutes. The only difference is that the thread which processes your request can now process other requests meanwhile database does its job. And when database finishes, the thread will continue process your request.
Say you have limited number of threads capable to process HTTP request. This async code will help you to process more requests per time period, but it won't help user to get the job done faster.
This seems to be down to a misunderstanding as to what async and await do.
async does not mean run this on a new thread, in essence it acts as a signal to the compiler to build a state machine, so a method like this:
Task<int> GetMeAnInt()
{
return await myWebService.GetMeAnInt();
}
sort of (cannot stress this enough), gets turned into this:
Task<int> GetMeAnInt()
{
var awaiter = myWebService.GetMeAnInt().GetAwaiter();
awaiter.OnCompletion(() => goto done);
return Task.InProgress;
done:
return awaiter.Result;
}
MSDN has way more information about this, and there's even some code out there explaining how to build your own awaiters.
async and await at their very core just enable you to write code that uses callbacks under the hood, but in a nice way that tells the compiler to do the heavy lifting for you.
If you really want to run something in the background, then you need to use Task:
Task<int> GetMeAnInt()
{
return Task.Run(() => myWebService.GetMeAnInt());
}
OR
Task<int> GetMeAnInt()
{
return Task.Run(async () => await myWebService.GetMeAnInt());
}
The second example uses async and await in the lambda because in this scenario GetMeAnInt on the web service also happens to return Task<int>.
To recap:
async and await just instruct the compiler to do some jiggerypokery
This uses labels and callbacks with goto
Fun fact, this is valid IL but the C# compiler doesn't allow it for your own code, hence why the compiler can get away with the magic but you can't.
async does not mean "run on a background thread"
Task.Run() can be used to queue a threadpool thread to run an arbitrary function
Task.Factory.Start() can be used to grab a brand new thread to run an arbitrary function
await instructs the compiler that this is the point at which the result of the awaiter for the awaitable (e.g. Task) being awaited is required - this is how it knows how to structure the state machine.
As I describe in my MSDN article on async ASP.NET, async is not a silver bullet; it doesn't change the HTTP protocol:
When some developers learn about async and await, they believe it’s a way for the server code to “yield” to the client (for example, the browser). However, async and await on ASP.NET only “yield” to the ASP.NET runtime; the HTTP protocol remains unchanged, and you still have only one response per request.
In your case, you're trying to use a web request to kick off a backend operation and then return to the browser. ASP.NET was not designed to execute backend operations like this; it is only a web tier framework. Having ASP.NET execute work is dangerous because ASP.NET is only aware of work coming in from its requests.
I have an overview of various solutions on my blog. Note that using a plain Task.Run, Task.Factory.StartNew, or ThreadPool.QueueUserWorkItem is extremely dangerous because ASP.NET doesn't know anything about that work. At the very least you should use HostingEnvironment.QueueBackgroundWorkItem so ASP.NET at least knows about the work. But that doesn't guarantee that the work will actually ever complete.
A proper solution is to place the work in a persistent queue and have an independent background worker process that queue. See the Asynchronous Messaging Primer (specifically, your scenario is "Decoupling workloads").

Categories