In my service layer I wanted to fire multiple methods asynchronously and await for their results.
I tried with one at a time and it is erroring out.
In my service class I called the method like
var _validChapterCodesTask = gd.validateChapterCodeDetails(_input1);
await Task.WhenAll(_validChapterCodesTask);
var _chapterCodeResult = await _validChapterCodesTask;
And in DAL class the method definition looks like
public async Task<IEnumerable<ChapterCodeValidationOutput>> validateChapterCodeDetails(GroupMembershipValidationInput gmvi)
{
Repository rep = new Repository();
if (!gmvi._chapterCodes.All(x => x.Equals("")))
{
var _validChapterCodes = await rep.ExecuteStoredProcedureAsync<Entities.Upload.ChapterCodeValidationOutput>(SQL.Upload.UploadValidation.getChapterCodeValidationSQL(gmvi._chapterCodes),null);
return _validChapterCodes;
}
else
return new List<ChapterCodeValidationOutput>();
}
Error message
Error 208 The await operator can only be used within an async method. Consider marking this method with the async modifier and changing its return type to Task<ARC.Donor.Business.Upload.GroupMembershipValidationOutput>. C:\Users\m1034699\Desktop\Stuart_Upgrade_2.1_New Approach\Stuart_Export_Upload_v2.1\Stuart Web Service\ARC.Donor.Service\Upload\UploadValidationServices.cs 34 13 ARC.Donor.Service
in lines
await Task.WhenAll(_validChapterCodesTask);
var _chapterCodeResult = await _validChapterCodesTask;
What am I doing wrong ?
The error message is very explicit. It is telling you that you're Service class method is incorrectly attempting to use the async keyword. In order to fix this, you should be using "Async all the way" as defined in Stephen Cleary's post on MSDN as a best practice.
For example, if you're service class has a method body that is working with Task or Task<T>, or attempting to use the await keyword the method signature for this corresponding method body must be async (as the async keyword enables a method to use the await keyword). Additionally this method itself should also be Task or Task<T> returning, with very few exceptions to that rule.
Personally, I would alter your DAL class to simply return the operation that represents the asynchronous work without actually awaiting it. If you think about it, the body of the validateChapterCodeDetails method does not actually need to do anything with the results, it just needs to return them (instead of materializing them there). Consider the following:
public Task<IEnumerable<ChapterCodeValidationOutput>>
validateChapterCodeDetails(GroupMembershipValidationInput gmvi)
{
var rep = new Repository();
return gmvi._chapterCodes.All(x => x.Equals(""))
? new List<ChapterCodeValidationOutput>()
: rep.ExecuteStoredProcedureAsync
<Entities.Upload.ChapterCodeValidationOutput>
(SQL.Upload.UploadValidation
.getChapterCodeValidationSQL(gmvi._chapterCodes),null)
}
Since your Task<IEnumerable<ChapterCodeValidationOutput>> variable has already been awaited, you can access the .Result property to get what you're looking for.
Then in your Service class your method would look like this:
public async Task ConsumeAsync()
{
var _validChapterCodesTask = gd.validateChapterCodeDetails(_input1);
await Task.WhenAll(_validChapterCodesTask);
var _chapterCodeResult = _validChapterCodesTask.Result;
// Do something with it...
}
Here is a .NET fiddle that should help to exemplify this for you better.
NOTE
I would also caution using IEnumerable as it pertains to your repo, you should ensure that the results from the Database are not occurring via deferred execution, otherwise you risk the potential for connection issues, i.e.; unintentionally leaving a connection open, or not properly closing one.
In the Service class where you call
var _validChapterCodesTask = gd.validateChapterCodeDetails(_input1);
await Task.WhenAll(_validChapterCodesTask);
var _chapterCodeResult = await _validChapterCodesTask;
add a async to the method signature where await Task.WhenAll(_validChapterCodesTask); is called. And when this method also has a return type you have to wrap this type in a Task like the exception shows:
Task<ARC.Donor.Business.Upload.GroupMembershipValidationOutput>
E.g. if you have the following method:
public GroupMemberShipValidationOutput validate(..) {
...
await Task.WhenAll(_validChapterCodesTask);
...
}
You have to change the method signature to:
public async Task<GroupMemberShipValidationOutput> validate(..) {
...
await Task.WhenAll(_validChapterCodesTask);
...
}
Related
I am using .net core 6.0. I am getting this error when I am calling same method from different places. I tried calling this method GetEmployeeByEmployeeNumber from inside Index and I dont get any error and the method returns the object employee with value values populated in employee
public async Task<IActionResult> Index()
{
EmployeeInfo employee = await _employeeService.GetEmployeeByEmployeeNumber(up.EmployeeId);
PopulatePDFDoc();
return View();
}
public async Task<EmployeeInfo?> GetEmployeeByEmployeeNumber(string employeeId)
{
List<int> emplyoeeInfoId = new List<int>();
UserPrincipal up = utilities.UserADIdentity.GetADUserInfo(WindowsIdentity.GetCurrent().Name.ToString());
emplyoeeInfoId = _ackContext.EmployeeInfos.Where(e => e.EmployeeNumber == employeeId).OrderBy(e => e.DateFormFilled).Select(e => e.EmployeeInfoId).ToList();
var employee = await _ackContext.EmployeeInfos.Include(e => e.EmergencyInfos.Where(p => p.EmployeeInfoId.Equals(emplyoeeInfoId.LastOrDefault()))).Where(e=>e.EmployeeInfoId.Equals(emplyoeeInfoId.LastOrDefault())).FirstOrDefaultAsync();
return employee;
}
If I call the same method GetEmployeeByEmployeeNumber from inside PopulatePDFDoc(); then I get an error saying System.InvalidOperationException: 'Invalid operation. The connection is closed.'
below is my PopulatePDFDoc
public async void PopulatePDFDoc()
{
AckPackage.Data.PDFPopulate.DocPDF doc = new Data.PDFPopulate.DocPDF();
EmployeeInfo employee = await _employeeService.GetEmployeeByEmployeeNumber(up.EmployeeId);
}
below is the screen shot of the error:
I am new to .net core. Any help on this will be highly appreciated.
You need to await the call to PopulatePDFDoc() inside the Index method.
Like this:
await PopulatePDFDoc();
Always use await when calling an async method!
The reason you’re getting a “connection closed” error, is because the call to PopulatePDFDoc() is not being “awaited”, and the server request ends before the asynchronous method can run.
Also, PopulatePDFDoc() should return Task instead of void, like this:
public async Task PopulatePDFDoc()
Another thing I noticed that may cause you issues is your _ackContext which looks like it's a class-wide member variable based on the snippet you shared, meaning that same context-instance is shared between multiple methods.
However the context itself is actually not "thread safe", as can be read in Microsofts documentation here: https://learn.microsoft.com/en-us/ef/ef6/fundamentals/working-with-dbcontext which means that if multiple async methods use the same context - which they do in your example - you may run into issues.
The recommended approach is to create the context when you need it, and use the using syntax to make sure it's disposed properly after your work is finished. Like this:
using (var ackContext = new EmployeeContext())
{
// Perform data access using the context here
}
Try using that in your GetEmployeeByEmployeeNumber method and see if it helps as well :)
Does it make sense to call only one async private method and await for it in another async method?
Example:
private async Task<string> ReadMyFileAsync()
{
var streamReader = new StreamReader(#"c:\myFile.txt")
return await streamReader.ReadToEndAsync(); // <-- Does it make sense for me here to await for only onething, while the caller of the method ReadMyFileAsync is already an async method?
// By ignoring that the stream should be disposed...
}
private string ReadMyFile()
{
var streamReader = new StreamReader(#"c:\myFile.txt")
return streamReader.ReadToEnd();
// By ignoring that the stream should be disposed...
}
public async void OnFileChangedHandler()
{
// Some work...
var myText = await ReadMyFileAsync(); <-- Does it make any difference whether I called `await ReadMyFileAsync()` or `ReadMyFile()`?
var someThingElse = await SomeThingElse(...);
// Some work...
}
In the scenario above, what I guess, even if the method ReadMyFileAsync was called in its syncronous version (without using async and by using ReadToEnd() instead of await ReadToEndAsync()), it will keep acting the same, because the caller method is an async method. Which means in my opinion, this will make sense only if I am trying to read multiple files in paralell (see the following as example), is that right?
private async Task<string> ReadMyFileAsync() // <-- This makes sense for me
{
var streamReader1 = new StreamReader(#"c:\myFile1.txt");
var streamReader2 = new StreamReader(#"c:\myFile2.txt");
var streamReader3 = new StreamReader(#"c:\myFile3.txt");
var myText1Task = streamReader1.ReadToEndAsync();
var myText2Task = streamReader2.ReadToEndAsync();
var myText3Task = streamReader3.ReadToEndAsync();
return await myText1Task + await myText2Task + await myText3Task;
// By ignoring that the streams should be disposed...
}
So the question is simply, in the first block of code, does it make any difference whether I called ReadMyFileAsync or ReadMyFile?
Update: The whole question simplified is:
If I am going to await for the async method ReadMyFileAsync inside my async method OnFileChangedHandler, why would I use ReadMyFileAsync over ReadMyFile?
It depends. If you really only call one other method and you have no side effects, then you could just return the Task instead of awaiting it and returning the result wrapped in a task.
However, even in your example, you have side effects. You need to .Dispose something and you need to know when to do that. So you cannot just return the task, you need to wait until it's finished, then dispose your resources and then return the result of the finished task. Since it's "not that simple" even in your own boiled down example, the answer is: it does make sense. You have to decide case-by-case.
Sometimes you can just pass the task along, then the method does not need to be async at all, it just needs to return a Task and sometimes you need to do things based on the timing of tasks (i.e. do this only after that other thing is finished) and then you need to use async methods because you want to await results.
Yes, you should prefer async methods over sync because async methods doesn't block the executing thread. In UI apps it means that UI won't freeze. In Server apps it means that your server will be able to run more concurrent work without starving the threads.
Is there any scenario where writing method like this:
public async Task<SomeResult> DoSomethingAsync()
{
// Some synchronous code might or might not be here... //
return await DoAnotherThingAsync();
}
instead of this:
public Task<SomeResult> DoSomethingAsync()
{
// Some synchronous code might or might not be here... //
return DoAnotherThingAsync();
}
would make sense?
Why use return await construct when you can directly return Task<T> from the inner DoAnotherThingAsync() invocation?
I see code with return await in so many places, I think I might have missed something. But as far as I understand, not using async/await keywords in this case and directly returning the Task would be functionally equivalent. Why add additional overhead of additional await layer?
There is one sneaky case when return in normal method and return await in async method behave differently: when combined with using (or, more generally, any return await in a try block).
Consider these two versions of a method:
Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return foo.DoAnotherThingAsync();
}
}
async Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return await foo.DoAnotherThingAsync();
}
}
The first method will Dispose() the Foo object as soon as the DoAnotherThingAsync() method returns, which is likely long before it actually completes. This means the first version is probably buggy (because Foo is disposed too soon), while the second version will work fine.
If you don't need async (i.e., you can return the Task directly), then don't use async.
There are some situations where return await is useful, like if you have two asynchronous operations to do:
var intermediate = await FirstAsync();
return await SecondAwait(intermediate);
For more on async performance, see Stephen Toub's MSDN article and video on the topic.
Update: I've written a blog post that goes into much more detail.
The only reason you'd want to do it is if there is some other await in the earlier code, or if you're in some way manipulating the result before returning it. Another way in which that might be happening is through a try/catch that changes how exceptions are handled. If you aren't doing any of that then you're right, there's no reason to add the overhead of making the method async.
Another case you may need to await the result is this one:
async Task<IFoo> GetIFooAsync()
{
return await GetFooAsync();
}
async Task<Foo> GetFooAsync()
{
var foo = await CreateFooAsync();
await foo.InitializeAsync();
return foo;
}
In this case, GetIFooAsync() must await the result of GetFooAsync because the type of T is different between the two methods and Task<Foo> is not directly assignable to Task<IFoo>. But if you await the result, it just becomes Foo which is directly assignable to IFoo. Then the async method just repackages the result inside Task<IFoo> and away you go.
If you won't use return await you could ruin your stack trace while debugging or when it's printed in the logs on exceptions.
When you return the task, the method fulfilled its purpose and it's out of the call stack.
When you use return await you're leaving it in the call stack.
For example:
Call stack when using await:
A awaiting the task from B => B awaiting the task from C
Call stack when not using await:
A awaiting the task from C, which B has returned.
Making the otherwise simple "thunk" method async creates an async state machine in memory whereas the non-async one doesn't. While that can often point folks at using the non-async version because it's more efficient (which is true) it also means that in the event of a hang, you have no evidence that that method is involved in the "return/continuation stack" which sometimes makes it more difficult to understand the hang.
So yes, when perf isn't critical (and it usually isn't) I'll throw async on all these thunk methods so that I have the async state machine to help me diagnose hangs later, and also to help ensure that if those thunk methods ever evolve over time, they'll be sure to return faulted tasks instead of throw.
This also confuses me and I feel that the previous answers overlooked your actual question:
Why use return await construct when you can directly return Task from the inner DoAnotherThingAsync() invocation?
Well sometimes you actually want a Task<SomeType>, but most time you actually want an instance of SomeType, that is, the result from the task.
From your code:
async Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return await foo.DoAnotherThingAsync();
}
}
A person unfamiliar with the syntax (me, for example) might think that this method should return a Task<SomeResult>, but since it is marked with async, it means that its actual return type is SomeResult.
If you just use return foo.DoAnotherThingAsync(), you'd be returning a Task, which wouldn't compile. The correct way is to return the result of the task, so the return await.
Another reason for why you may want to return await: The await syntax lets you avoid hitting a mismatch between Task<T> and ValueTask<T> types. For example, the code below works even though SubTask method returns Task<T> but its caller returns ValueTask<T>.
async Task<T> SubTask()
{
...
}
async ValueTask<T> DoSomething()
{
await UnimportantTask();
return await SubTask();
}
If you skip await on the DoSomething() line, you'll get a compiler error CS0029:
Cannot implicitly convert type 'System.Threading.Tasks.Task<BlaBla>' to 'System.Threading.Tasks.ValueTask<BlaBla>'.
You'll get CS0030 too, if you try to explicitly typecast it.
This is .NET Framework, by the way. I can totally foresee a comment saying "that's fixed in .NET hypothetical_version", I haven't tested it. :)
Another problem with non-await method is sometimes you cannot implicitly cast the return type, especially with Task<IEnumerable<T>>:
async Task<List<string>> GetListAsync(string foo) => new();
// This method works
async Task<IEnumerable<string>> GetMyList() => await GetListAsync("myFoo");
// This won't work
Task<IEnumerable<string>> GetMyListNoAsync() => GetListAsync("myFoo");
The error:
Cannot implicitly convert type 'System.Threading.Tasks.Task<System.Collections.Generic.List>' to 'System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable>'
Imagine this is a method performing a DB query and returning a result, which in case of null is replaced with a default value (Null object pattern).
public ResultObj Get()
{
var result = dbContext.GetSomeResult();
return result ?? ResultObj.NullValue;
}
Imagine this DB query is a long-running process, so I would use async/await to execute this process in a separate thread. Suppose that the dbContext.GetSomeResultAsync() method is available.
How can be this method converted in an asynchronous one so that I can write something like this?
var resultTask = GetAsync();
var otherResultTask = GetSomethingElseAsync();
Task.WaitAll(resultTask, otherResultTask);
var myResult = resultTask.Result;
var myOtherResult = otherResultTask.Result;
I tried this solution.
public async Task<ResultObj> GetAsync()
{
var result = await dbContext.GetSomeResultAsync();
return result ?? ResultObj.NullValue;
}
First, I'm wondering why this code compiles: why can I return ResultObj when Task<ResultObj> is expected?
Second, this code predictably results in a deadlock, as clearly explained by the great number of resources about async deadlocks anti-patterns. The deadlock can be prevented by using .ConfigureAwait(false) method after the async call. Is this the right way to go? Are there any hidden drawbacks in this case? Is it a general rule?
I also tried this.
public async Task<ResultObj> GetAsync()
{
return await Task.Run(() => {
var result = dbContext.GetSomeResult();
return result ?? ResultObj.NullValue;
});
}
This results in a deadlock, too. This time I cannot even figure out why.
Edit: possible solution
Finally, after having read this, I found a solution to my problem.
My generic query wrapper method is like this.
public async Task<ResultObj> GetAsync()
{
var result = await dbContext.GetSomeResultAsync();
return result ?? ResultObj.NullValue;
}
On calling method, I use this pattern.
public async Task<CollectedResults> CollectAsync()
{
var resultTask = GetAsync();
var otherResultTask = GetSomethingElseAsync();
//here both queries are being executed.
//...in the while, optionally, here some other synchronous actions
//then, await results
var result = await resultTask;
var otherResult = await otherResultTask;
//here process collected results and return
return new CollectedResults(...);
}
It is worth mentioning that the above code, wrapped in a domain class, is called by a Controller action. In order for this to work I had to make async the methods all the way up, until Controller action, which now appears as follows.
public async Task<CollectedResults> Get()
{
return await resultsCollector.CollectAsync();
}
This way, deadlock doesn't happen anymore and execution time greatly improves with respect to the synchronous version.
I don't know if this is the canonical way of executing parallel queries. But it works and I don't see particular pitfalls in the code.
First of all, regarding :
so I would use async/await to execute this process in a separate thread.
There is no new thread created when we use async and await
Secondly:
why can I return ResultObj when Task is expected?
the Task<TResult> as return type of method tells that it returns a Task of type TResult but we need to return object of type that TResult back from it so the method can be awaited and when using Task<TResult> as reutrn type we should be using async and await to do the work.
Lastly:
this code predictably results in a deadlock
You are using async keyword with method signatures and also await the next async method call being done from within the method. So apparently it looks like the code in first example you have posted shouldn't be deadlocked, if the method GetSomeResultAsync you are consuming is really a async method and is properly implemented.
I suggest to study more about the async await before getting in to it, following is a good article to start with:
https://blog.stephencleary.com/2012/02/async-and-await.html
In my data access layer I'm attempting to create methods with return types of Task.
I cannot get the return type from the entity framework to return Task<List<MYtype>>
public static Task<List<ILeaf>> GetLeafs(int doorID)
{
using (var db = new StorefrontSystemEntities())
{
return db.proc_GetDoorLeafs(doorID).ToList<ILeaf>();
};
}
Is the only way to make this run correctly is to format the code like so:
public async static Task<List<ILeaf>> GetLeafs(int doorID)
{
return await Task.Run(() =>
{
using (var db = new StorefrontSystemEntities())
{
return db.proc_GetDoorLeafs(doorID).ToList<ILeaf>();
};
});
}
The reason I was asking is because I would like to give the option to run async, or am I not understanding this correctly?
If I can just return a Task then on the calling end I could give the option to await if I wanted to run async, but if i wanted to run synchronously I would just call the method as normal.
If I'm returning a Task do I always have to include the async keyword in the method signature?
Am I thinking about this the wrong way? If I've got a return type of Task then the method has the option of being called async or synchronously?
But, if I have async and Task in the method signature then the method runs async no matter what?
Thanks!
So to answer the literal question asked, you can just do this:
public static Task<List<ILeaf>> GetLeafs(int doorID)
{
return Task.Run(() =>
{
using (var db = new StorefrontSystemEntities())
{
return db.proc_GetDoorLeafs(doorID).ToList<ILeaf>();
};
});
}
That said, note that this isn't a particularly useful method. The idea of leveraging asynchronous programming is that you don't want to have a thread pool thread sitting there doing nothing but waiting on this IO operation. Ideally you'd leverage IO that is inherently asynchronous in nature; a method that itself naturally returns a task.
You aren't really providing value to consumers of your code by wrapping the blocking IO in a call to Task.Run. If they need that operation to be run in a background thread they can do so on their own, and then they'll know more precisely that it's not a naively asynchronous operation.
See Should I expose asynchronous wrappers for synchronous methods? for more information on the subject.
public static async Task<List<ILeaf>> GetLeafs(int doorID)
{
using (var db = new StorefrontSystemEntities())
{
var result = db.proc_GetDoorLeafs(doorID).ToList<ILeaf>();
return await Task.FromResult(result);
}
}