← Back
IAmTimCorey July 5, 2026 32m

Task vs ValueTask in C#

Read full transcript 28 segments
  1. Working with async tasks in C-sharp is Working with async tasks in C-sharp is both easy and complex at the same time. both easy and complex at the same time. both easy and complex at the same time. But now there's a new type that you But now there's a new type that you But now there's a new type that you should at least understand called value should at least understand called value should at least understand called value task. In this video, I'm going to show task. In this video, I'm going to show task. In this video, I'm going to show you what value task is and how it you what value task is and how it you what value task is and how it compares to the regular task. And then compares to the regular task. And then compares to the regular task. And then we'll discuss when to use each in your we'll discuss when to use each in your we'll discuss when to use each in your code as well as the best practices. code as well as the best practices. code as well as the best practices. Now software developers should approach Now software developers should approach Now software developers should approach almost every problem with it depends. almost every problem with it depends. almost every problem with it depends. But in order to do that, you need to But in order to do that, you need to But in order to do that, you need to first understand what your options are first understand what your options are first understand what your options are and then what the trade-offs are going and then what the trade-offs are going and then what the trade-offs are going to be. That's just one of the reasons to be. That's just one of the reasons to be. That's just one of the reasons why having a great foundation in why having a great foundation in why having a great foundation in software development is so critical even software development is so critical even software development is so critical even light of AI. light of AI. light of AI. And that's why I provide detailed And that's why I provide detailed And that's why I provide detailed real-world training every Monday in real-world training every Monday in real-world training every Monday in C-sharp and the related technologies as C-sharp and the related technologies as C-sharp and the related technologies as well as developer advice every Thursday. well as developer advice every Thursday. well as developer advice every Thursday. Now, if you want to increase your skills Now, if you want to increase your skills Now, if you want to increase your skills and make yourself even more valuable to and make yourself even more valuable to and make yourself even more valuable to an employer, I offer paid training at an employer, I offer paid training at an employer, I offer paid training at IAmTimCorey.com. IAmTimCorey.com. IAmTimCorey.com. That paid training funds the free That paid training funds the free That paid training funds the free training like this so that everyone can training like this so that everyone can training like this so that everyone can have a great education C-sharp, not just have a great education C-sharp, not just have a great education C-sharp, not just those who can afford it. All right, those who can afford it. All right, those who can afford it. All right, let's talk about how tasks work to begin let's talk about how tasks work to begin let's talk about how tasks work to begin with. So, in our our C-sharp code, we with. So, in our our C-sharp code, we with. So, in our our C-sharp code, we create a variable, we say this is going create a variable, we say this is going create a variable, we say this is going to be the the task, right? So this if to be the the task, right? So this if to be the the task, right? So this if you have an async method, it returns a you have an async method, it returns a you have an async method, it returns a task or a task of type T.

  2. task or a task of type T. task or a task of type T. And so that task gets allocated onto the And so that task gets allocated onto the And so that task gets allocated onto the stack eight bytes. That eight bytes is stack eight bytes. That eight bytes is stack eight bytes. That eight bytes is just a pointer. So, if you're not just a pointer. So, if you're not just a pointer. So, if you're not familiar with the stack and the heap, um familiar with the stack and the heap, um familiar with the stack and the heap, um I actually have a a course in my site I actually have a a course in my site I actually have a a course in my site called 100 interview training questions called 100 interview training questions called 100 interview training questions and this is one of them because this is and this is one of them because this is and this is one of them because this is one of those things where it's is both one of those things where it's is both one of those things where it's is both theoretical and really practical to theoretical and really practical to theoretical and really practical to understand the difference. So, in basic understand the difference. So, in basic understand the difference. So, in basic terms, this is this is way basic. But terms, this is this is way basic. But terms, this is this is way basic. But basically, the stack is information that basically, the stack is information that basically, the stack is information that gets allocated just inside the method gets allocated just inside the method gets allocated just inside the method you're running. When a method is over, you're running. When a method is over, you're running. When a method is over, that data gets blown away. It's it's that data gets blown away. It's it's that data gets blown away. It's it's super easy, it's super fast, and it's super easy, it's super fast, and it's super easy, it's super fast, and it's super cheap to create because super cheap to create because super cheap to create because when the method is done, the compiler when the method is done, the compiler when the method is done, the compiler knows, "Okay, I can" or .NET knows that, knows, "Okay, I can" or .NET knows that, knows, "Okay, I can" or .NET knows that, "Okay, I can just delete all that memory "Okay, I can just delete all that memory "Okay, I can just delete all that memory usage." usage." usage." That's the stack. Now, the heap is That's the stack. Now, the heap is That's the stack. Now, the heap is something different. In object-oriented something different. In object-oriented something different. In object-oriented programming, when we create an instance programming, when we create an instance programming, when we create an instance of an object, we're not creating a a um of an object, we're not creating a a um of an object, we're not creating a a um like we have that that pointer basically like we have that that pointer basically like we have that that pointer basically that passes around. It's not a pointer, that passes around. It's not a pointer, that passes around. It's not a pointer, but it's kind of like that. We pass but it's kind of like that. We pass but it's kind of like that. We pass around and say, "Okay, this is my person around and say, "Okay, this is my person around and say, "Okay, this is my person instance." Well, that instance isn't instance." Well, that instance isn't instance." Well, that instance isn't what's actually getting passed around.

  3. what's actually getting passed around. what's actually getting passed around. You're passing around the 8-bit address You're passing around the 8-bit address You're passing around the 8-bit address for where it's located in the heap. for where it's located in the heap. for where it's located in the heap. Okay? The problem is it's not a problem, Okay? The problem is it's not a problem, Okay? The problem is it's not a problem, but it's it's a but it's it's a but it's it's a it's more expensive to do this because it's more expensive to do this because it's more expensive to do this because in the heap, well, this memory lasts in the heap, well, this memory lasts in the heap, well, this memory lasts beyond this stack. beyond this stack. beyond this stack. So, you can have two different methods So, you can have two different methods So, you can have two different methods that both have this an 8-point 8-bit uh that both have this an 8-point 8-bit uh that both have this an 8-point 8-bit uh or 8-byte uh pointer that points to the or 8-byte uh pointer that points to the or 8-byte uh pointer that points to the location in the heap. That means the location in the heap. That means the location in the heap. That means the data in the heap has to live longer than data in the heap has to live longer than data in the heap has to live longer than the methods. the methods. the methods. And so, what happens is the data in the And so, what happens is the data in the And so, what happens is the data in the heap, well, at some point it gets it heap, well, at some point it gets it heap, well, at some point it gets it gets bigger and bigger and bigger, and gets bigger and bigger and bigger, and gets bigger and bigger and bigger, and that's where your memory usage gets that's where your memory usage gets that's where your memory usage gets chewed up. And so, we have a thing chewed up. And so, we have a thing chewed up. And so, we have a thing called a garbage collector. And if called a garbage collector. And if called a garbage collector. And if you're ever trying to adjust the garbage you're ever trying to adjust the garbage you're ever trying to adjust the garbage collector, stop. Don't do that. Let it collector, stop. Don't do that. Let it collector, stop. Don't do that. Let it do its thing. But, what it's going to do do its thing. But, what it's going to do do its thing. But, what it's going to do is say, "Okay, we have some memory is say, "Okay, we have some memory is say, "Okay, we have some memory pressure. We need to reduce the pressure. We need to reduce the pressure. We need to reduce the pressure." And what it does is it looks pressure." And what it does is it looks pressure." And what it does is it looks for things in the heap that are no for things in the heap that are no for things in the heap that are no longer referenced anywhere in any stack.

  4. longer referenced anywhere in any stack. longer referenced anywhere in any stack. And it says, "Okay, I can get rid of And it says, "Okay, I can get rid of And it says, "Okay, I can get rid of these things. They're no longer needed these things. They're no longer needed these things. They're no longer needed anywhere. I can delete them off the anywhere. I can delete them off the anywhere. I can delete them off the heap." But, that takes resources. heap." But, that takes resources. heap." But, that takes resources. Which is why Which is why Which is why if at all possible, we like to put if at all possible, we like to put if at all possible, we like to put things in the stack. So, integers and things in the stack. So, integers and things in the stack. So, integers and doubles and all things like that always doubles and all things like that always doubles and all things like that always go in the stack. And so, go in the stack. And so, go in the stack. And so, they're very easy to take They go away, they're very easy to take They go away, they're very easy to take They go away, right? And so, but the the downside of right? And so, but the the downside of right? And so, but the the downside of that is that if you pass an integer from that is that if you pass an integer from that is that if you pass an integer from method to method to method, you're method to method to method, you're method to method to method, you're making copies of that. Which means that making copies of that. Which means that making copies of that. Which means that the data that costs for that integer the data that costs for that integer the data that costs for that integer goes in the stack multiple times. goes in the stack multiple times. goes in the stack multiple times. Now, the stack is very cheap. So, that's Now, the stack is very cheap. So, that's Now, the stack is very cheap. So, that's a high-level overview, right? So, a task a high-level overview, right? So, a task a high-level overview, right? So, a task When we have a task, When we have a task, When we have a task, it which is a whatever you are calling it which is a whatever you are calling it which is a whatever you are calling an async method, you're going to have a an async method, you're going to have a an async method, you're going to have a task. task. task. You get an 8-byte You get an 8-byte You get an 8-byte um entry in the stack that points to a um entry in the stack that points to a um entry in the stack that points to a location in the heap. Now, in the heap, location in the heap. Now, in the heap, location in the heap. Now, in the heap, it's about 80 bytes. It depends on the it's about 80 bytes. It depends on the it's about 80 bytes. It depends on the task, if it's a task or a task of type task, if it's a task or a task of type task, if it's a task or a task of type T. Um and then, you know, what it does, T. Um and then, you know, what it does, T. Um and then, you know, what it does, it holds a bunch of different it holds a bunch of different it holds a bunch of different information. Like, is that task information. Like, is that task information. Like, is that task complete? And here's the the output or complete? And here's the the output or complete? And here's the the output or results from this task. And here's Did results from this task. And here's Did results from this task. And here's Did it succeed or not? And all that it succeed or not? And all that it succeed or not? And all that information. It's very efficient, but it information. It's very efficient, but it information. It's very efficient, but it creates an entry in the heap for every creates an entry in the heap for every creates an entry in the heap for every task. Now, the output is separate from task. Now, the output is separate from task. Now, the output is separate from that. So, if you're going to return a that. So, if you're going to return a that. So, if you're going to return a list of T, and so, you wrap that a task list of T, and so, you wrap that a task list of T, and so, you wrap that a task if it's async, then you're going to have

  5. if it's async, then you're going to have if it's async, then you're going to have the output in a sep- in a separate the output in a sep- in a separate the output in a sep- in a separate place, probably in the heap, um place, probably in the heap, um place, probably in the heap, um compared to the actual task information. compared to the actual task information. compared to the actual task information. And then, of course, the stack has that And then, of course, the stack has that And then, of course, the stack has that reference to the heap for the task and reference to the heap for the task and reference to the heap for the task and then the the output. Okay, so that's how then the the output. Okay, so that's how then the the output. Okay, so that's how a task works in general. I know it's a task works in general. I know it's a task works in general. I know it's it's kind of nerdy. It's kind of, you it's kind of nerdy. It's kind of, you it's kind of nerdy. It's kind of, you know, do I care about this stuff? know, do I care about this stuff? know, do I care about this stuff? Usually not too much. But just so you Usually not too much. But just so you Usually not too much. But just so you know, every time you create a task, some know, every time you create a task, some know, every time you create a task, some stuff goes in the heap, and that can put stuff goes in the heap, and that can put stuff goes in the heap, and that can put some memory pressures on things if some memory pressures on things if some memory pressures on things if you're doing a lot of work, you're doing a lot of work, you're doing a lot of work, and this is where value task comes in. and this is where value task comes in. and this is where value task comes in. Because value task says, "Hey, what if Because value task says, "Hey, what if Because value task says, "Hey, what if we didn't have to put something in the we didn't have to put something in the we didn't have to put something in the heap?" heap?" heap?" And so, what they did was they created And so, what they did was they created And so, what they did was they created the value task. Now, the value task the value task. Now, the value task the value task. Now, the value task in the stack, instead of being an 8-byte in the stack, instead of being an 8-byte in the stack, instead of being an 8-byte pointer, it's actually about 24 bytes. pointer, it's actually about 24 bytes. pointer, it's actually about 24 bytes. And this lives in the stack, the value And this lives in the stack, the value And this lives in the stack, the value task uh entry, the variable, lives in task uh entry, the variable, lives in task uh entry, the variable, lives in the stack. What's the benefit there?

  6. the stack. What's the benefit there? the stack. What's the benefit there? Well, there is no allocation on the Well, there is no allocation on the Well, there is no allocation on the heap. heap. heap. So, if you create a value task, there's So, if you create a value task, there's So, if you create a value task, there's no allocation on the heap, no allocation on the heap, no allocation on the heap, it's just in the stack. And again, the it's just in the stack. And again, the it's just in the stack. And again, the stack is very, very cheap. stack is very, very cheap. stack is very, very cheap. And then, of course, just to be very And then, of course, just to be very And then, of course, just to be very clear, the the output here is the same. clear, the the output here is the same. clear, the the output here is the same. So, it's not like you're saving anything So, it's not like you're saving anything So, it's not like you're saving anything in the output. What you're saving is in the output. What you're saving is in the output. What you're saving is this heap allocation right here. There's this heap allocation right here. There's this heap allocation right here. There's no heap allocation in theory for a value no heap allocation in theory for a value no heap allocation in theory for a value task. task. task. Now, let's get into how these two work, Now, let's get into how these two work, Now, let's get into how these two work, and why you know, because the first and why you know, because the first and why you know, because the first question you're going to ask is, "Well, question you're going to ask is, "Well, question you're going to ask is, "Well, why wouldn't I always use a value task?" why wouldn't I always use a value task?" why wouldn't I always use a value task?" And the answer is actually, you probably And the answer is actually, you probably And the answer is actually, you probably almost always want to use a task, not a almost always want to use a task, not a almost always want to use a task, not a value task, but there is a time and a value task, but there is a time and a value task, but there is a time and a place for this. place for this. place for this. The the basic answer is that you should The the basic answer is that you should The the basic answer is that you should be always using task. be always using task. be always using task. However, when you find that your app has However, when you find that your app has However, when you find that your app has some memory issues, and you're finding some memory issues, and you're finding some memory issues, and you're finding that usually the result of the return that usually the result of the return that usually the result of the return from that async method is actually from that async method is actually from that async method is actually synchronous. Remember, uh when you do an synchronous. Remember, uh when you do an synchronous. Remember, uh when you do an async call, you use a task, that does async call, you use a task, that does async call, you use a task, that does not mean that your method's actually not mean that your method's actually not mean that your method's actually doing async work.

  7. doing async work. doing async work. It may do synchronous work, It may do synchronous work, It may do synchronous work, and just return it wrapped in a task. and just return it wrapped in a task. and just return it wrapped in a task. So, if you were mostly returning So, if you were mostly returning So, if you were mostly returning information synchronously, information synchronously, information synchronously, then you may get some value out of doing then you may get some value out of doing then you may get some value out of doing a value task instead. a value task instead. a value task instead. Cuz what happens is if all the Cuz what happens is if all the Cuz what happens is if all the synchronous work avoids entirely this synchronous work avoids entirely this synchronous work avoids entirely this heap for a value task. But, when it heap for a value task. But, when it heap for a value task. But, when it needs to, it can do asynchronous work, needs to, it can do asynchronous work, needs to, it can do asynchronous work, too. In that case, it will wrap it, too. In that case, it will wrap it, too. In that case, it will wrap it, it'll put actually call a task behind it'll put actually call a task behind it'll put actually call a task behind the scenes. So, the scenes. So, the scenes. So, there's some some tweaks here. We're there's some some tweaks here. We're there's some some tweaks here. We're going to see what this all means. Yes, going to see what this all means. Yes, going to see what this all means. Yes, this is all theoretical right now. I this is all theoretical right now. I this is all theoretical right now. I want to make it concrete with some code, want to make it concrete with some code, want to make it concrete with some code, but I want to kind of give you a but I want to kind of give you a but I want to kind of give you a high-level overview of the differences high-level overview of the differences high-level overview of the differences between the two. between the two. between the two. So, a task is whatever you want to do So, a task is whatever you want to do So, a task is whatever you want to do asynchronously. asynchronously. asynchronously. A value task is reserved for It makes A value task is reserved for It makes A value task is reserved for It makes the most sense for whenever you are the most sense for whenever you are the most sense for whenever you are returning information that has mostly returning information that has mostly returning information that has mostly synchronous calls. You might say, "Well, synchronous calls. You might say, "Well, synchronous calls. You might say, "Well, why would I ever have a method that's why would I ever have a method that's why would I ever have a method that's async return synchronous stuff?" Well, async return synchronous stuff?" Well, async return synchronous stuff?" Well, we're going to see in our example, a we're going to see in our example, a we're going to see in our example, a really really common way that value task really really common way that value task really really common way that value task is beneficial is if you're asking for is beneficial is if you're asking for is beneficial is if you're asking for data from a cache.

  8. data from a cache. data from a cache. Because that cache data is probably Because that cache data is probably Because that cache data is probably synchronous. It's right there. And so, synchronous. It's right there. And so, synchronous. It's right there. And so, you don't have to go out to the API or you don't have to go out to the API or you don't have to go out to the API or out to the database to get new data very out to the database to get new data very out to the database to get new data very often. You're going to the cache. Well, often. You're going to the cache. Well, often. You're going to the cache. Well, the cache is going to be a synchronous the cache is going to be a synchronous the cache is going to be a synchronous call almost always. call almost always. call almost always. Now, if you have a cache somewhere else, Now, if you have a cache somewhere else, Now, if you have a cache somewhere else, maybe it's not. But, if your cache is maybe it's not. But, if your cache is maybe it's not. But, if your cache is local, then you're going to be making a local, then you're going to be making a local, then you're going to be making a synchronous call behind the scenes. synchronous call behind the scenes. synchronous call behind the scenes. And more often than not, hopefully, you And more often than not, hopefully, you And more often than not, hopefully, you know, 99% plus of your calls will be know, 99% plus of your calls will be know, 99% plus of your calls will be then synchronous to that cache. then synchronous to that cache. then synchronous to that cache. Which means you will save a bunch of Which means you will save a bunch of Which means you will save a bunch of heap storage, heap storage, heap storage, which causes bloat, causes memory which causes bloat, causes memory which causes bloat, causes memory issues. You'll save a bunch of that by issues. You'll save a bunch of that by issues. You'll save a bunch of that by using value task. using value task. using value task. There are downsides, we're going to look There are downsides, we're going to look There are downsides, we're going to look at those. But, let's go over to the at those. But, let's go over to the at those. But, let's go over to the code. Now, I've already started writing code. Now, I've already started writing code. Now, I've already started writing some code here. This is a console some code here. This is a console some code here. This is a console application in .NET 10. application in .NET 10. application in .NET 10. And what I've done is in the program.cs, And what I've done is in the program.cs, And what I've done is in the program.cs, I just set up a benchmark with I just set up a benchmark with I just set up a benchmark with Benchmark.NET Benchmark.NET Benchmark.NET to run this cache benchmark.

  9. to run this cache benchmark. to run this cache benchmark. And the cache benchmark is not filled in And the cache benchmark is not filled in And the cache benchmark is not filled in yet, but basically we've got yet, but basically we've got yet, but basically we've got some setup that's empty, and then we some setup that's empty, and then we some setup that's empty, and then we have two methods. We're going to have a have two methods. We're going to have a have two methods. We're going to have a task example, which is not implemented task example, which is not implemented task example, which is not implemented yet, and we're going to have a value yet, and we're going to have a value yet, and we're going to have a value task example, also not implemented yet. task example, also not implemented yet. task example, also not implemented yet. So, that's the the comparison we'll do, So, that's the the comparison we'll do, So, that's the the comparison we'll do, and we'll just see and we'll just see and we'll just see where we see the benefits of one versus where we see the benefits of one versus where we see the benefits of one versus the other. Now, to do this, I have tried the other. Now, to do this, I have tried the other. Now, to do this, I have tried as much as possible to get everything as much as possible to get everything as much as possible to get everything else out of the way. Because when you're else out of the way. Because when you're else out of the way. Because when you're doing benchmarks, doing benchmarks, doing benchmarks, if you're not careful, if you're not careful, if you're not careful, what you're actually benchmarking is, what you're actually benchmarking is, what you're actually benchmarking is, say, the API call as opposed to the task say, the API call as opposed to the task say, the API call as opposed to the task versus value task. Which is why what I versus value task. Which is why what I versus value task. Which is why what I did was we have this person record here, did was we have this person record here, did was we have this person record here, first name and last name, that's all it first name and last name, that's all it first name and last name, that's all it is. And for the people data access, it's is. And for the people data access, it's is. And for the people data access, it's just going to create a a list with three just going to create a a list with three just going to create a a list with three entries in it, same three entries every entries in it, same three entries every entries in it, same three entries every time, and return it. Now, I did put in time, and return it. Now, I did put in time, and return it. Now, I did put in here here here the await task.yield, the await task.yield, the await task.yield, okay? This is used to ensure that it's okay? This is used to ensure that it's okay? This is used to ensure that it's truly an async call. So, I want to make truly an async call. So, I want to make truly an async call. So, I want to make sure that that's sure that that's sure that that's pointed out. Because normally what you pointed out. Because normally what you pointed out. Because normally what you do here is you would call out to an API do here is you would call out to an API do here is you would call out to an API or something else. That would be truly or something else. That would be truly or something else. That would be truly an async call. But, because I'm just an async call. But, because I'm just an async call. But, because I'm just doing sample code, if you're not doing sample code, if you're not doing sample code, if you're not careful, that'd mess the benchmark up careful, that'd mess the benchmark up careful, that'd mess the benchmark up because it's actually synchronous.

  10. because it's actually synchronous. because it's actually synchronous. But, we're truly saying task.yield, But, we're truly saying task.yield, But, we're truly saying task.yield, which makes sure it's asynchronous um which makes sure it's asynchronous um which makes sure it's asynchronous um every time you call this. every time you call this. every time you call this. So, that's why it's marked as async, and So, that's why it's marked as async, and So, that's why it's marked as async, and that's what we'll use for making our that's what we'll use for making our that's what we'll use for making our calls. So, that's the that's the sample calls. So, that's the that's the sample calls. So, that's the that's the sample or set code. By the way, if you want the or set code. By the way, if you want the or set code. By the way, if you want the result of all of this code, you can result of all of this code, you can result of all of this code, you can download that down the description. download that down the description. download that down the description. There's a a link to get an email to There's a a link to get an email to There's a a link to get an email to um download this source code. um download this source code. um download this source code. Okay, so let's work on creating our Okay, so let's work on creating our Okay, so let's work on creating our example. So, what we're going to do is example. So, what we're going to do is example. So, what we're going to do is we'll create a new we'll create a new we'll create a new um control shift A and a new class. um control shift A and a new class. um control shift A and a new class. We'll call this task example. We'll call this task example. We'll call this task example. Or I try to keep this very close as Or I try to keep this very close as Or I try to keep this very close as possible to the same thing, task versus possible to the same thing, task versus possible to the same thing, task versus value task. value task. value task. So, what we're going to do is we're So, what we're going to do is we're So, what we're going to do is we're going to create a method or a yeah, going to create a method or a yeah, going to create a method or a yeah, method in here that is going to read method in here that is going to read method in here that is going to read from a cache. from a cache. from a cache. So, first off, I want to So, first off, I want to So, first off, I want to um um um let's do a constructor.

  11. let's do a constructor. let's do a constructor. And in here, I want a time span. Just so I don't have to hard code it. Just so I don't have to hard code it. And we're going to say uh cache And we're going to say uh cache And we're going to say uh cache lifetime. lifetime. lifetime. So, So, So, >> [snorts] >> [snorts] >> [snorts] >> caches have a lifetime and at some point >> caches have a lifetime and at some point >> caches have a lifetime and at some point they reset. So, let's make sure we have they reset. So, let's make sure we have they reset. So, let's make sure we have one for this. So, private read only one for this. So, private read only one for this. So, private read only time span and this is the cache time span and this is the cache time span and this is the cache lifetime. lifetime. lifetime. And then we'll say And then we'll say And then we'll say cache lifetime equals cache lifetime. Like so. Like so. And that's going to be our constructor. And that's going to be our constructor. And that's going to be our constructor. And what we're going to do is we're And what we're going to do is we're And what we're going to do is we're going to going to going to um let's add a couple more variables up um let's add a couple more variables up um let's add a couple more variables up here while we're here. Uh private list of person record list of person record and we'll call this let's make it and we'll call this let's make it and we'll call this let's make it nullable and call it cache. nullable and call it cache. nullable and call it cache. And then private date time is going to And then private date time is going to And then private date time is going to be cache be cache be cache last refreshed time.

  12. last refreshed time. last refreshed time. So, this is the last time the cache So, this is the last time the cache So, this is the last time the cache refreshed. refreshed. refreshed. So, note that, you know, 1 second. And So, note that, you know, 1 second. And So, note that, you know, 1 second. And so, we're going to say, "Okay, is it 1 so, we're going to say, "Okay, is it 1 so, we're going to say, "Okay, is it 1 second second second past this this time? And if so, then past this this time? And if so, then past this this time? And if so, then refresh the cache. refresh the cache. refresh the cache. Okay. So, now let's create a method down Okay. So, now let's create a method down Okay. So, now let's create a method down here. We're call it private async task here. We're call it private async task here. We're call it private async task of type list of type person record. of type list of type person record. of type list of type person record. And this will be called load people. And what we're going to do is say cache And what we're going to do is say cache equals equals equals await await await people data access people data access people data access {dot} get people async. {dot} get people async. {dot} get people async. So, remember that people data access So, remember that people data access So, remember that people data access right here? right here? right here? That's what we're calling in this That's what we're calling in this That's what we're calling in this method. So, we're going to put that data method. So, we're going to put that data method. So, we're going to put that data into the cache. into the cache. into the cache. And then we're going to say cache last And then we're going to say cache last And then we're going to say cache last time refreshed equals datetime.utcnow. And then return the cache as well And then return the cache as well because we're saying, "Hey, here's the because we're saying, "Hey, here's the because we're saying, "Hey, here's the cache cache cache the the new data." Um the the new data." Um the the new data." Um which is this is an async call. This is which is this is an async call. This is which is this is an async call. This is always an async call. This is just set always an async call. This is just set always an async call. This is just set up work. So, now we have a way to load up work. So, now we have a way to load up work. So, now we have a way to load the or update the cache.

  13. the or update the cache. the or update the cache. Now, let's create our get people task. Now, let's create our get people task. Now, let's create our get people task. So, public So, public So, public task list of task list of task list of person record. And here, what we're going to do is And here, what we're going to do is normally normally normally we're hoping that we hit the the cache. we're hoping that we hit the the cache. we're hoping that we hit the the cache. So, we're going to say, "If So, we're going to say, "If So, we're going to say, "If cache is not null cache is not null cache is not null and and and datetime datetime datetime {dot} utcnow {dot} utcnow {dot} utcnow minus cache minus cache minus cache last refresh time last refresh time last refresh time is less than is less than is less than cache lifetime. cache lifetime. cache lifetime. So, as long as we're within that So, as long as we're within that So, as long as we're within that whatever the lifespan is. Let's say we whatever the lifespan is. Let's say we whatever the lifespan is. Let's say we we do 1 minute. we do 1 minute. we do 1 minute. So, if we do 1 minute, which we're going So, if we do 1 minute, which we're going So, if we do 1 minute, which we're going to do shortly than for our benchmark. to do shortly than for our benchmark. to do shortly than for our benchmark. But, if we do 1 minute, then as long as But, if we do 1 minute, then as long as But, if we do 1 minute, then as long as the time now minus the cache last the time now minus the cache last the time now minus the cache last refresh time is less than a minute, refresh time is less than a minute, refresh time is less than a minute, then we're going to go to the cache and then we're going to go to the cache and then we're going to go to the cache and use the cache data.

  14. use the cache data. use the cache data. So, that would be return So, that would be return So, that would be return task.fromresult task.fromresult task.fromresult cache. cache. cache. So, here we're doing is wrapping So, here we're doing is wrapping So, here we're doing is wrapping [clears throat] the cache in a [clears throat] the cache in a [clears throat] the cache in a task.fromresult because we're not doing task.fromresult because we're not doing task.fromresult because we're not doing an async call here, we are accessing the an async call here, we are accessing the an async call here, we are accessing the cache. So, we're just returning the cache. So, we're just returning the cache. So, we're just returning the data, but when you have an async method, data, but when you have an async method, data, but when you have an async method, then you have to make sure that um let's then you have to make sure that um let's then you have to make sure that um let's mark this async. Um when you have an async method, then Um when you have an async method, then you have to have a task or task of type you have to have a task or task of type you have to have a task or task of type T. So, we're have to wrap this cache in T. So, we're have to wrap this cache in T. So, we're have to wrap this cache in a task in order to return it. a task in order to return it. a task in order to return it. Now, if Now, if Now, if that's not the case, we return load that's not the case, we return load that's not the case, we return load people. Okay? So, oops, you don't have to mark Okay? So, oops, you don't have to mark this as async. Sorry. Um we don't have this as async. Sorry. Um we don't have this as async. Sorry. Um we don't have to mark this async because we're not to mark this async because we're not to mark this async because we're not actually doing any awaits here. We're actually doing any awaits here. We're actually doing any awaits here. We're just returning the results. So, we're just returning the results. So, we're just returning the results. So, we're returning this async for uh load people.

  15. returning this async for uh load people. returning this async for uh load people. And what this will do is we can await And what this will do is we can await And what this will do is we can await that call then and get the cache data that call then and get the cache data that call then and get the cache data out of it. So, this is a normal way to out of it. So, this is a normal way to out of it. So, this is a normal way to to access a cache to access a cache to access a cache is we say, "Hey, if the cache is is we say, "Hey, if the cache is is we say, "Hey, if the cache is available and it's not expired, then go available and it's not expired, then go available and it's not expired, then go ahead and return that cache data." ahead and return that cache data." ahead and return that cache data." Otherwise, Otherwise, Otherwise, refresh the cache right there, refresh the cache right there, refresh the cache right there, and then make sure you say the cache has and then make sure you say the cache has and then make sure you say the cache has been refreshed as of now, and then been refreshed as of now, and then been refreshed as of now, and then return that cache data, return that cache data, return that cache data, the new cache data. So, this is a normal the new cache data. So, this is a normal the new cache data. So, this is a normal way to um way to um way to um to do a a task, do a synchronous call. to do a a task, do a synchronous call. to do a a task, do a synchronous call. And this is what you need to do by And this is what you need to do by And this is what you need to do by default default default is have a task and then we can await is have a task and then we can await is have a task and then we can await that. Now, we'll do that in that. Now, we'll do that in that. Now, we'll do that in uh the cache benchmark where in here for uh the cache benchmark where in here for uh the cache benchmark where in here for our task example. our task example. our task example. Actually, we should probably bring in um Actually, we should probably bring in um Actually, we should probably bring in um we should probably instantiate these up we should probably instantiate these up we should probably instantiate these up here. here. here. And say private task example, make it And say private task example, make it And say private task example, make it nullable and say underscore task nullable and say underscore task nullable and say underscore task example.

  16. And then in our setup, And then in our setup, we'll say task example equals new and we'll say task example equals new and we'll say task example equals new and then pass in time span then pass in time span then pass in time span um um um >> [clears throat] >> [clears throat] >> [clears throat] >> from seconds and say one. So, it's going >> from seconds and say one. So, it's going >> from seconds and say one. So, it's going to be a 1-second cache timeout. Really to be a 1-second cache timeout. Really to be a 1-second cache timeout. Really short. short. short. But that means that down here, we can But that means that down here, we can But that means that down here, we can say say say task example task example task example dot uh get people task like so. And then dot uh get people task like so. And then dot uh get people task like so. And then we'll actually return we'll actually return we'll actually return await this. await this. await this. And we should also mark this as yes, And we should also mark this as yes, And we should also mark this as yes, this is not going to be null. this is not going to be null. this is not going to be null. Okay. So, a couple of things to note Okay. So, a couple of things to note Okay. So, a couple of things to note here. First of all, I use the here. First of all, I use the here. First of all, I use the exclamation point here because this is exclamation point here because this is exclamation point here because this is marked as nullable because we first marked as nullable because we first marked as nullable because we first instantiate the class, it will be null. instantiate the class, it will be null. instantiate the class, it will be null. But [snorts] But [snorts] But [snorts] in the setup, we make sure we in the setup, we make sure we in the setup, we make sure we instantiate, therefore it will not be instantiate, therefore it will not be instantiate, therefore it will not be null when we get here. null when we get here. null when we get here. We're returning an await of this, which We're returning an await of this, which We're returning an await of this, which means it will return the actual data. means it will return the actual data. means it will return the actual data. Okay. So, Okay. So, Okay. So, this for us is going to this for us is going to this for us is going to run the task example.

  17. run the task example. run the task example. So, it's going to say, "Hey, let's get So, it's going to say, "Hey, let's get So, it's going to say, "Hey, let's get the people task." Which get the people the people task." Which get the people the people task." Which get the people task is going to either return from the task is going to either return from the task is going to either return from the cache or it's going to load the cache up cache or it's going to load the cache up cache or it's going to load the cache up and then return the value. and then return the value. and then return the value. So, again, this is normal stuff. This is So, again, this is normal stuff. This is So, again, this is normal stuff. This is normal way of of accessing cache and normal way of of accessing cache and normal way of of accessing cache and doing a synchronous work. doing a synchronous work. doing a synchronous work. However, what we want to do is we want However, what we want to do is we want However, what we want to do is we want to switch over to a value task. So, what to switch over to a value task. So, what to switch over to a value task. So, what I'm going to do is I'm actually going to I'm going to do is I'm actually going to I'm going to do is I'm actually going to copy all this task stuff, um copy all this task stuff, um copy all this task stuff, um but not the actual task example. but not the actual task example. but not the actual task example. So, So, So, copy all the contents of the class. copy all the contents of the class. copy all the contents of the class. And control shift A and say value task And control shift A and say value task And control shift A and say value task example. example. example. And we'll get rid of the using And we'll get rid of the using And we'll get rid of the using directives. directives. directives. And I'm going to paste in Watch me make And I'm going to paste in Watch me make And I'm going to paste in Watch me make it public first. it public first. it public first. I'll paste in the contents of what was a I'll paste in the contents of what was a I'll paste in the contents of what was a task example. Notice that I have to task example. Notice that I have to task example. Notice that I have to change the constructor to be the right change the constructor to be the right change the constructor to be the right name.

  18. Now, this is an exact copy. Now, this is an exact copy. This is exactly the same thing we did This is exactly the same thing we did This is exactly the same thing we did before. before. before. Which is we have to change for being a Which is we have to change for being a Which is we have to change for being a value task. But, I wanted it to be an value task. But, I wanted it to be an value task. But, I wanted it to be an exact copy. Then, I want to show you exact copy. Then, I want to show you exact copy. Then, I want to show you what's different. what's different. what's different. So, here instead of returning task, So, here instead of returning task, So, here instead of returning task, we're going to return value task. we're going to return value task. we're going to return value task. Which changes how this works. Which changes how this works. Which changes how this works. So, instead of returning this, and I'll So, instead of returning this, and I'll So, instead of returning this, and I'll actually just comment this out actually just comment this out actually just comment this out temporarily so you can see it, temporarily so you can see it, temporarily so you can see it, I'm going to say new value task I'm going to say new value task I'm going to say new value task of type list of person record. And cache. And cache. So, instead of saying task.fromresult, So, instead of saying task.fromresult, So, instead of saying task.fromresult, we're saying new value task of this we're saying new value task of this we're saying new value task of this type. type. type. That's the difference here. That's the difference here. That's the difference here. Okay? That's one, but then we have down Okay? That's one, but then we have down Okay? That's one, but then we have down here here here load people. Well, that's the same load people. Well, that's the same load people. Well, that's the same thing. Let's copy this part of it. thing. Let's copy this part of it. thing. Let's copy this part of it. Right to here. Right to here. Right to here. And say wrap this whole thing in a value And say wrap this whole thing in a value And say wrap this whole thing in a value task. So, new value task list of type task. So, new value task list of type task. So, new value task list of type person record and load people. But, person record and load people. But, person record and load people. But, notice this returns an async task. We're notice this returns an async task. We're notice this returns an async task. We're not changing that. That still works the not changing that. That still works the not changing that. That still works the same way.

  19. same way. same way. It's just we're saying that we're It's just we're saying that we're It's just we're saying that we're returning a value task from get people, returning a value task from get people, returning a value task from get people, uh let's just say get people value task. uh let's just say get people value task. uh let's just say get people value task. Instead of get people task. Instead of get people task. Instead of get people task. So, So, So, we are returning a value task instead of we are returning a value task instead of we are returning a value task instead of a task. And the benefit here is since a task. And the benefit here is since a task. And the benefit here is since most of the time most of the time most of the time we do this cache result, which is just we do this cache result, which is just we do this cache result, which is just going to be returning a synchronous going to be returning a synchronous going to be returning a synchronous value, not making anything asynchronous value, not making anything asynchronous value, not making anything asynchronous behind the scenes, then we're going to behind the scenes, then we're going to behind the scenes, then we're going to save a bunch of memory. save a bunch of memory. save a bunch of memory. So, So, So, that's the only change we're going to that's the only change we're going to that's the only change we're going to make. I know this is dense stuff, but I make. I know this is dense stuff, but I make. I know this is dense stuff, but I want to give you an example working and want to give you an example working and want to give you an example working and we'll talk more about the high level of we'll talk more about the high level of we'll talk more about the high level of this now that you have an example to this now that you have an example to this now that you have an example to see. see. see. Okay, let's go back to the cache Okay, let's go back to the cache Okay, let's go back to the cache benchmark and of course we need to down benchmark and of course we need to down benchmark and of course we need to down here, actually up here first, let's say here, actually up here first, let's say here, actually up here first, let's say private value task private value task private value task example example example is value task example.

  20. If I spell right. If I spell right. And then we're going to say value task And then we're going to say value task And then we're going to say value task example equals new time span from example equals new time span from example equals new time span from seconds seconds seconds and say one. So, we're doing the exact and say one. So, we're doing the exact and say one. So, we're doing the exact same thing here. same thing here. same thing here. And then down here for our value task And then down here for our value task And then down here for our value task example, we're going to say return await example, we're going to say return await example, we're going to say return await value task example and again, we're value task example and again, we're value task example and again, we're going to say exclamation point to say going to say exclamation point to say going to say exclamation point to say yes, we know it's not null yes, we know it's not null yes, we know it's not null {dot} get people value task. {dot} get people value task. {dot} get people value task. So, it's the exact same call, So, it's the exact same call, So, it's the exact same call, the exact same operation, we're just the exact same operation, we're just the exact same operation, we're just doing a value task instead of a task. doing a value task instead of a task. doing a value task instead of a task. Okay. Okay. Okay. So, with all of that being done, it's a So, with all of that being done, it's a So, with all of that being done, it's a lot of setup work, it's a lot of lot of setup work, it's a lot of lot of setup work, it's a lot of you know, task and async and all the you know, task and async and all the you know, task and async and all the rest. But once all this is done, what we rest. But once all this is done, what we rest. But once all this is done, what we what we're end up with is let's run a what we're end up with is let's run a what we're end up with is let's run a benchmark. To do this, what we're going benchmark. To do this, what we're going benchmark. To do this, what we're going to do is actually to do is actually to do is actually open in File Explorer open in File Explorer open in File Explorer and then I'm going to say open terminal.

  21. and then I'm going to say open terminal. and then I'm going to say open terminal. So, the reason for this is I prefer this So, the reason for this is I prefer this So, the reason for this is I prefer this terminal to the one built into Visual terminal to the one built into Visual terminal to the one built into Visual Studio. Studio. Studio. So, I'm going to say dotnet run -c in So, I'm going to say dotnet run -c in So, I'm going to say dotnet run -c in release. So, this is going to run in release. So, this is going to run in release. So, this is going to run in release mode. Right now, we're in debug release mode. Right now, we're in debug release mode. Right now, we're in debug mode normally and we can just hit go. mode normally and we can just hit go. mode normally and we can just hit go. We want to run in release mode. We want We want to run in release mode. We want We want to run in release mode. We want to be disconnected from Visual Studio. I to be disconnected from Visual Studio. I to be disconnected from Visual Studio. I like this best. It's It's clean. It's like this best. It's It's clean. It's like this best. It's It's clean. It's simple and it makes sure that we're not simple and it makes sure that we're not simple and it makes sure that we're not going to pollute our test with anything going to pollute our test with anything going to pollute our test with anything extra. Um ah. extra. Um ah. extra. Um ah. CD CD CD uh ValueTaskExplanationApp. I didn't spell it right. Um I didn't spell it right. Um CD Let's CD Let's CD Let's dir. Uh CD ValueTaskExplanation. dir. Uh CD ValueTaskExplanation. dir. Uh CD ValueTaskExplanation. That's why. That's why. That's why. There we go. So, we were in the solution There we go. So, we were in the solution There we go. So, we were in the solution directory, not the the project directory, not the the project directory, not the the project directory. The project directory is directory. The project directory is directory. The project directory is where the actual um executable is or the where the actual um executable is or the where the actual um executable is or the the execution is run from. So, we're the execution is run from. So, we're the execution is run from. So, we're going to run the project, not the going to run the project, not the going to run the project, not the solution.

  22. solution. solution. So, we're going to run -c release from So, we're going to run -c release from So, we're going to run -c release from here. here. here. So, So, So, this is going to compile our project in this is going to compile our project in this is going to compile our project in release mode. It's going to make sure release mode. It's going to make sure release mode. It's going to make sure that we're not doing anything extra. that we're not doing anything extra. that we're not doing anything extra. And then it's going to run a whole bunch And then it's going to run a whole bunch And then it's going to run a whole bunch of operations. Notice this number of of operations. Notice this number of of operations. Notice this number of operations we're running um that's in operations we're running um that's in operations we're running um that's in what, the 33 million operations it looks what, the 33 million operations it looks what, the 33 million operations it looks like. Um like. Um like. Um so, it's going to run a lot of these and so, it's going to run a lot of these and so, it's going to run a lot of these and it's going to compare these two to each it's going to compare these two to each it's going to compare these two to each other. other. other. So, So, So, yes, this is a lot of uh setup work and yes, this is a lot of uh setup work and yes, this is a lot of uh setup work and a lot of work. But, let's talk briefly a lot of work. But, let's talk briefly a lot of work. But, let's talk briefly about what we're doing. about what we're doing. about what we're doing. We are when We are when We are when when we don't have to when we don't have to when we don't have to worry about the result coming back being worry about the result coming back being worry about the result coming back being mostly asynchronous. When the results mostly asynchronous. When the results mostly asynchronous. When the results coming back are probably going to be coming back are probably going to be coming back are probably going to be synchronous behind the scenes for an synchronous behind the scenes for an synchronous behind the scenes for an async call. And we're doing a lot of async call. And we're doing a lot of async call. And we're doing a lot of them, them, them, then a value task can give us extra then a value task can give us extra then a value task can give us extra performance. Which means that we performance. Which means that we performance. Which means that we probably do not want to use value task probably do not want to use value task probably do not want to use value task except in very specific circumstances.

  23. except in very specific circumstances. except in very specific circumstances. So, you might have watched the video at So, you might have watched the video at So, you might have watched the video at this point and go, "Wait, Tim. What this point and go, "Wait, Tim. What this point and go, "Wait, Tim. What you're saying is I almost never want to you're saying is I almost never want to you're saying is I almost never want to use this?" The answer is yes. You almost use this?" The answer is yes. You almost use this?" The answer is yes. You almost never want to use this. But, you do want never want to use this. But, you do want never want to use this. But, you do want to know about it because when it comes to know about it because when it comes to know about it because when it comes time to make your app more performant, time to make your app more performant, time to make your app more performant, this may be one of the areas where you this may be one of the areas where you this may be one of the areas where you address. You might say, "This is the address. You might say, "This is the address. You might say, "This is the area that's going to be the the area I area that's going to be the the area I area that's going to be the the area I can make some changes to make my app a can make some changes to make my app a can make some changes to make my app a little bit more performant, or a lot little bit more performant, or a lot little bit more performant, or a lot more performant, especially in terms of more performant, especially in terms of more performant, especially in terms of memory." memory." memory." So, here we go. Here's the kind of the So, here we go. Here's the kind of the So, here we go. Here's the kind of the the meat and potatoes results of all of the meat and potatoes results of all of the meat and potatoes results of all of this. Task example versus value task this. Task example versus value task this. Task example versus value task example. example. example. Now, Now, Now, the task example is a little slower than the task example is a little slower than the task example is a little slower than the value task example. That's because the value task example. That's because the value task example. That's because we're doing more asynchronous work here we're doing more asynchronous work here we're doing more asynchronous work here um versus here, I believe. But, um versus here, I believe. But, um versus here, I believe. But, really means we're just allocating a really means we're just allocating a really means we're just allocating a little bit more on the heap. Okay. So, little bit more on the heap. Okay. So, little bit more on the heap. Okay. So, right here, gen zero allocated and the right here, gen zero allocated and the right here, gen zero allocated and the ratio. So, we've allocated 144 ratio. So, we've allocated 144 ratio. So, we've allocated 144 bytes bytes bytes on average for this task example.

  24. on average for this task example. on average for this task example. So, that's not a ton, 144 bytes. So, that's not a ton, 144 bytes. So, that's not a ton, 144 bytes. But, that's compared to nothing. But, that's compared to nothing. But, that's compared to nothing. Which means that we're saving that 144 Which means that we're saving that 144 Which means that we're saving that 144 bytes every time we make a call where it bytes every time we make a call where it bytes every time we make a call where it is is is a synchronous result, where the cache a synchronous result, where the cache a synchronous result, where the cache gets called. gets called. gets called. So, if you're doing a million cache hits So, if you're doing a million cache hits So, if you're doing a million cache hits an hour, well, you're saving a million an hour, well, you're saving a million an hour, well, you're saving a million times 144 bytes. times 144 bytes. times 144 bytes. That could be a significant savings. That could be a significant savings. That could be a significant savings. However, However, However, if you're not if you're not if you're not technically, the value task is going to technically, the value task is going to technically, the value task is going to be a bit more memory intensive in the be a bit more memory intensive in the be a bit more memory intensive in the the uh stack and it's going to cause a the uh stack and it's going to cause a the uh stack and it's going to cause a couple other things where couple other things where couple other things where it's a little bit more expensive. it's a little bit more expensive. it's a little bit more expensive. Because the upfront cost is a little bit Because the upfront cost is a little bit Because the upfront cost is a little bit more expensive, but over time cost is more expensive, but over time cost is more expensive, but over time cost is cheaper than the task example if you're cheaper than the task example if you're cheaper than the task example if you're mostly doing synchronous work. mostly doing synchronous work. mostly doing synchronous work. So, again, probably the most So, again, probably the most So, again, probably the most if I had to give you one, which is what if I had to give you one, which is what if I had to give you one, which is what I did, um if I had to give you one I did, um if I had to give you one I did, um if I had to give you one example of where this might benefit you, example of where this might benefit you, example of where this might benefit you, and where you might want to look first, and where you might want to look first, and where you might want to look first, is when you're talking to your cache.

  25. is when you're talking to your cache. is when you're talking to your cache. This is a very common pattern in This is a very common pattern in This is a very common pattern in software development, where you have a software development, where you have a software development, where you have a cache to make things more performant. cache to make things more performant. cache to make things more performant. So, that way you're not talking to the So, that way you're not talking to the So, that way you're not talking to the database every single time you want a database every single time you want a database every single time you want a list of, let's say, the states in the list of, let's say, the states in the list of, let's say, the states in the US. Like, you don't you don't want to go US. Like, you don't you don't want to go US. Like, you don't you don't want to go to the database every time a person to the database every time a person to the database every time a person requests that, because that's silly. The requests that, because that's silly. The requests that, because that's silly. The The number of states in the US doesn't The number of states in the US doesn't The number of states in the US doesn't change that often. So, you want to make change that often. So, you want to make change that often. So, you want to make sure you go to the cache for that as sure you go to the cache for that as sure you go to the cache for that as much as possible, and that cache might much as possible, and that cache might much as possible, and that cache might live for days or weeks or even months. live for days or weeks or even months. live for days or weeks or even months. So, therefore, you have less and less So, therefore, you have less and less So, therefore, you have less and less actual syn- asynchronous calls going to actual syn- asynchronous calls going to actual syn- asynchronous calls going to the database for that information, and the database for that information, and the database for that information, and more and more calls are going uh more and more calls are going uh more and more calls are going uh synchronously and just grabbing that synchronously and just grabbing that synchronously and just grabbing that cache information. That's where I would cache information. That's where I would cache information. That's where I would look for potential savings, but here's look for potential savings, but here's look for potential savings, but here's the deal. You really want to run some the deal. You really want to run some the deal. You really want to run some kind of benchmark on this, and this is kind of benchmark on this, and this is kind of benchmark on this, and this is where I again show you benchmark.net. where I again show you benchmark.net. where I again show you benchmark.net. I've have a separate whole video on I've have a separate whole video on I've have a separate whole video on that. that. that. Um but you want to do a benchmark to Um but you want to do a benchmark to Um but you want to do a benchmark to make sure you're actually in the real make sure you're actually in the real make sure you're actually in the real world saving memory.

  26. world saving memory. world saving memory. Because this is not just one of those Because this is not just one of those Because this is not just one of those things where you guess. You try and things where you guess. You try and things where you guess. You try and figure out and make you know, look at figure out and make you know, look at figure out and make you know, look at the real world results of it. the real world results of it. the real world results of it. So, in this benchmark, we're seeing that So, in this benchmark, we're seeing that So, in this benchmark, we're seeing that we're saving a little bit every single we're saving a little bit every single we're saving a little bit every single time we do a value task as compared to a time we do a value task as compared to a time we do a value task as compared to a task. But only in this specific type of task. But only in this specific type of task. But only in this specific type of circumstance. Normally, this is not a circumstance. Normally, this is not a circumstance. Normally, this is not a savings. We'd actually be savings. We'd actually be savings. We'd actually be um um um increasing the amount of processing we increasing the amount of processing we increasing the amount of processing we do and and it'd be more expensive to run do and and it'd be more expensive to run do and and it'd be more expensive to run a value task. So, let's talk about the a value task. So, let's talk about the a value task. So, let's talk about the other parts of a value task. Now, other parts of a value task. Now, other parts of a value task. Now, there's a lot more I can go into. I there's a lot more I can go into. I there's a lot more I can go into. I don't want to waste your time going too don't want to waste your time going too don't want to waste your time going too too deep on this, but there are things too deep on this, but there are things too deep on this, but there are things you need to know about a value task. you need to know about a value task. you need to know about a value task. So, So, So, let's close this out. Oh, by the way, we let's close this out. Oh, by the way, we let's close this out. Oh, by the way, we hit enter finished up. So, it wasn't hit enter finished up. So, it wasn't hit enter finished up. So, it wasn't done until we hit enter. Um so, done until we hit enter. Um so, done until we hit enter. Um so, now let's minimize this and let's talk now let's minimize this and let's talk now let's minimize this and let's talk about a task versus a value task. Let's about a task versus a value task. Let's about a task versus a value task. Let's go to our cash benchmark.

  27. go to our cash benchmark. go to our cash benchmark. So, here I am returning an await. So, So, here I am returning an await. So, So, here I am returning an await. So, I'm saying, "Hey, we're returning it." I'm saying, "Hey, we're returning it." I'm saying, "Hey, we're returning it." Now, I could await this again. Now, I could await this again. Now, I could await this again. This method I could await this again. This method I could await this again. This method I could await this again. And And And um I could I could put the result of um I could I could put the result of um I could I could put the result of this task, this skippable task, I could this task, this skippable task, I could this task, this skippable task, I could put this into let's say a a win all or I put this into let's say a a win all or I put this into let's say a a win all or I could put this into could put this into could put this into an array and and keep track of these an array and and keep track of these an array and and keep track of these tasks. tasks. tasks. You don't want to do that with a value You don't want to do that with a value You don't want to do that with a value task. Value task, you want to treat it task. Value task, you want to treat it task. Value task, you want to treat it as a one-time return. as a one-time return. as a one-time return. So, when you await it, So, when you await it, So, when you await it, that's it. You're done. that's it. You're done. that's it. You're done. You you await it. If you want to go any You you await it. If you want to go any You you await it. If you want to go any further, you pass around the return further, you pass around the return further, you pass around the return value, not the value task. value, not the value task. value, not the value task. So, you're not When When it comes to So, you're not When When it comes to So, you're not When When it comes to value task, you're not going to use when value task, you're not going to use when value task, you're not going to use when all or get results. You're not going to all or get results. You're not going to all or get results. You're not going to store it and reuse it. Um and you're not store it and reuse it. Um and you're not store it and reuse it. Um and you're not going to await it multiple times. So, going to await it multiple times. So, going to await it multiple times. So, yes, there are some other limitations to yes, there are some other limitations to yes, there are some other limitations to it, but it, but it, but in the specific circumstances where you in the specific circumstances where you in the specific circumstances where you find that you need to do some find that you need to do some find that you need to do some optimization, value task can be a great optimization, value task can be a great optimization, value task can be a great tool to pull off the shelf.

  28. tool to pull off the shelf. tool to pull off the shelf. So, I feel it's important you know about So, I feel it's important you know about So, I feel it's important you know about it because it's one more tool in your it because it's one more tool in your it because it's one more tool in your toolbox, but I also want to make sure toolbox, but I also want to make sure toolbox, but I also want to make sure you know that it is not a common tool to you know that it is not a common tool to you know that it is not a common tool to use in the very limited circumstances use in the very limited circumstances use in the very limited circumstances where it is more valuable. But, when you where it is more valuable. But, when you where it is more valuable. But, when you come across those circumstances, it can come across those circumstances, it can come across those circumstances, it can be really valuable. It can save a lot of be really valuable. It can save a lot of be really valuable. It can save a lot of memory pressure. It can reduce the memory pressure. It can reduce the memory pressure. It can reduce the amount of work your your garbage amount of work your your garbage amount of work your your garbage collector's doing, and it can make your collector's doing, and it can make your collector's doing, and it can make your app overall more performant. You just app overall more performant. You just app overall more performant. You just have to use it in the right have to use it in the right have to use it in the right circumstances, okay? So, a bit more circumstances, okay? So, a bit more circumstances, okay? So, a bit more advanced topic today, but I figured I advanced topic today, but I figured I advanced topic today, but I figured I would uh cover this and kind of show you would uh cover this and kind of show you would uh cover this and kind of show you how this works and give you one more how this works and give you one more how this works and give you one more tool um so that you're more prepared for tool um so that you're more prepared for tool um so that you're more prepared for more situations. All right? Thanks for more situations. All right? Thanks for more situations. All right? Thanks for watching. As always, I am Tim Core. watching. As always, I am Tim Core. watching. As always, I am Tim Core. >> [music]

Summary

The transcript discusses the efficient handling of asynchronous operations in C# by introducing `ValueTask`. It explains how `ValueTask` offers performance benefits over the standard `Task` by leveraging stack allocation for synchronous operations. The practical takeaway is to understand the differences and choose the appropriate task type for optimized code, especially given the evolving landscape of software development.

View original episode ↗