-1

Can anyone explain to me what would happen in the following situation:

public int? getValue()
{
    return GetIntValue().Result;
}

public async Task<int?> GetIntValue()
{
    return await getId();
}

public async Task<int?> getId()
{
    return (await Context.Users.FirstOrDefaultAsync())?.AssignedUserId;
}

and if this situation is any different:

public int? getValue()
{
    return getId().Result;
}

Basically, I am wondering if the await here will cause the execution to continue before the result has been returned in either (or both cases), and if they are different, why are they different?

Alex
  • 3,730
  • 9
  • 43
  • 94

2 Answers2

4

This getId().Result; is a blocking call that possibly would result in a deadlock scenario. The current thread of execution would block until the function that is called to return.

On the other hand using the async/await approach you will not block. The thread that process this call, would stop and would be available for processing another call. Then when your function call would be completed, the result would be processed by another thread of the thread pool.

Now how the above blocking call would affect your application it depends on the type of your application. For instance if we are talking about a Windows Forms application or a WPF application and this code would be executed on the UI thread your form would freeze until this call being completed. On the other hand if this is a ASP.NET application and you have many requests hitting the server this can result in an exhaustion of the ASP.NET threads, whose purpose is to process the requests that server receives. Apparently, this would result in an application that doesn't respond to new requests, until the some of the requests server received get their response.

Regarding the deadlock scenario, please have a look at this question and especially at the first answer. At this you will find a link to an excellent article on this topic Don't Block on Async Code.

Christos
  • 53,228
  • 8
  • 76
  • 108
  • correct me, if im wrong, but this `getId().Result;` might deadlock in some cases, e.g. wpf/winform app – Taras Shcherban Oct 11 '18 at 12:39
  • @Christos why would it deadlock? Surely if it is blocking then once the db call was complete it would release the thread and continue executing? – Alex Oct 11 '18 at 12:40
  • @Shcherban You are absolutely correct. This is the very reason I mentioned that _may_ would result in a deadlock scenario. – Christos Oct 11 '18 at 12:40
  • @Christos does that not mean it would be the same as if there was not async await, as that is what would happen anyway eg the thread and application would block until the request was complete? – Alex Oct 11 '18 at 12:46
  • @Alex No, not quite. Mixing `await` and `.Result` can make two different threads wait for each other, creating a deadlock. That is certainly not possible without `await` – Camilo Terevinto Oct 11 '18 at 12:47
  • The deadlock are a possibility but not really that common and it's a bit of a talking point than a real problem. And also async is a keyword it doesn't do anything magical, you should investigate tasks TAP for a bit to understand wht async is doing – Filip Cordas Oct 11 '18 at 12:52
  • @CamiloTerevinto It most certainly *is* possible without `await`, it's just very, very easy to do with `await`, and less commonly done without it, as people end up creating continuations without realizing it, or without realizing what exactly they're doing (and also because it's rare to manually add continuations anymore at all). `await` is just a shorthand for manually creating the continuations though. – Servy Oct 11 '18 at 13:21
  • @Servy Yeah, I know, but as you say, it's not really common – Camilo Terevinto Oct 11 '18 at 13:25
  • @CamiloTerevinto There's a *world* of difference between, "That's not common", and, "That's certainly not possible". And of course it wasn't even that uncommon back when people were actually manually adding their own continuations frequently. It's really only uncommon these days because *any* use of manual continuations is uncommon. – Servy Oct 11 '18 at 13:27
0

It shall lead to the same result, both will wait until users are retrieved so getValue() method will return value and won't return null.

Michel Hanna
  • 157
  • 1
  • 10
  • i mean in that exact case as await in GetIntValue wouldn't have any much effect on asynchrony, as when i return control to the caller of the async method wouldn't find anything to do. what is your opinion? – Michel Hanna Oct 11 '18 at 12:55