Before/without Task<>s, I'm using a wrapper object like the below to encapsulate the result of an I/O operation that could fail, without propagating exceptions up the call stack:
public class FetchResult<T>
{
public readonly bool Success;
public readonly T Item;
public FetchResult(bool success, T item)
{
this.Success = success;
this.Item = item;
}
}
I'd use it like this:
var userResult = Get("robert.paulson#fightclub.com");
if(!userResult.Success)
// abort, or something
...
public FetchResult<User> Get(string email)
{
try
{
// go to database here, and get the User
return new FetchResult(true, new User());
}
catch
{
// log exception
return new FetchResult(false, null);
}
}
This works great for me as a model, as it allows me to effectively manage exceptions without using try/catch as program control flow and gives me easy and fine-grained graceful service degredation.
However, with the advent of Task<>, I could very easily end up with:
public Task<FetchResult<User>> GetAsync(string email)
which seems to be getting out of hand.
Seeing as I'm migrating to async everywhere anyway, I'm contemplating just doing:
public Task<User> GetAsync(string email)
which id have expected to allow me to do something like:
var userTask = GetAsync("robert.paulson#fightclub.com");
await userTask;
if(userTask.IsFaulted) // (*) - see below
// abort, or something
However if my GetAsync method returns:
return Task<User>.FromException(new Exception());
what is actually returned after the await (where the (*) comment is) seems to be a Completed Task, whos result is a Task<User> which is faulted.
Why am I getting a nested task in this case, and is there some syntactic sugar I'm missing to make this whole affair tidier?
There are two methods in Task library FromException() and FromException<TResult>() both are available via Task and Task<TResult>.
public static Task FromException(Exception exception)
{
return FromException<VoidTaskResult>(exception);
}
public static Task<TResult> FromException<TResult>(Exception exception)
{
...
...
}
If you call Task<TResult>.FromException() or Task.FromException() there's no different in these two calls.
Your method signature is: public Task<User> GetAsync(string email)
Now if you try to use Task<User>.FromException(new Exception()) this will return Task<VoidTaskResult> and which is ofcourse is not of type Task<User>. Which means you might be getting compiler error.
This compile time error would be gone if you use Task<User>.FromException<User>(new Exception()); or Task.FromException<User>(new Exception());
You're getting Task<Task<VoidTaskResult>> as specified in comments means there's something more in your method code which is not mentioned in your sample code.
For more internal details about Task methods in .Net source code see here
Update:
After looking at your code found couple of issues.
i) Return type as Task is avoiding the compilation error that I mentioned earlier in my answer.
ii) You're returning a Task with in a Async method without awaiting means the complete task object will be wrapped in Another Task type.
See below example that I tweaked to to show the problem. See even the return type is changed from Task of type Object to Program there's still no error. This is Because of Object which is base of any custom type in C#. So doing below is allowed:
static async Task<object> GetAsync()
{
try
{
throw new Exception();
}
catch (Exception e)
{
return Task.FromException<Program>(e);
}
}
Now change the return type of method to Task<Program> you'll get an error or more of warning.
Now the correct version to fix the problem would be to await the Task so that only Program type remain as result which will be automatically returned as Task<Program>.
Correct version:
static async Task<Program> GetAsync()
{
try
{
throw new Exception();
}
catch (Exception e)
{
return await Task.FromException<Program>(e);
}
}
Now you won't see any Nested tasks anymore. This is internals of how await works. If you really want know why it happens like this then try to analyze the IL generated of all the above 3 versions of the program using IL spy and you'll get the idea. Cheers!!!
Kind of unusual, but you can explore the fact that the Task.WhenAny method does not throw exception (see Is there a way to Wait for a TPL Task without in throwing an exception?) like this
var userTask = GetAsync("robert.paulson#fightclub.com");
await Task.WaitAny(userTask);
if(userTask.IsFaulted) // (*) - see below
// abort, or something
Task.IsFaulted means that the Task completed due to an unhandled exception. So I don't think you could set it in a different way than to let the exception go uncaught.
public async Task<User> GetAsync(string email)
{
// go to database here, and get the User
return new User();
}
Or catch, log, and rethrow:
public async Task<User> GetAsync(string email)
{
try
{
// go to database here, and get the User
return new User();
}
catch
{
// log exception
throw;
}
}
I believe you are saying that your GetAsync is returning a nested task because you have something like this:
public async Task GetAsync(string email)
{
// .... somewhere in the code
return Task.FromException(new Exception());
}
But when you declare a method using the async keyword, C# magic takes care of wrapping its contents inside a Task. So in this case you actually end up having a task which returns another task - Task<Task<T>>. It would return Task<T> if you removed the async keyword but then obviously you end up with a standard synchronous method.
Related
This question already has answers here:
Any difference between "await Task.Run(); return;" and "return Task.Run()"? [duplicate]
(4 answers)
Closed 8 years ago.
Is there any difference between the methods below? Is one preferable over the other?
public static async Task SendAsync1(string to, string subject, string htmlBody) {
// ...
await smtp.SendMailAsync(message);
// No return statement
}
public static Task SendAsync2(string to, string subject, string htmlBody) {
// ...
return smtp.SendMailAsync(message);
}
This method will be called from MVC controller methods; for example:
public async Task<ActionResult> RegisterUser(RegisterViewModel model)
{
// ...
await Mailer.SendAsync(user.Email, subject, body);
return View(model);
}
There are 2 practical differences:
The second option will not create the state machine mecanism that allows for async-await usage. That will have a minor positive effect on performance.
The exception handling would be a little different. When you mark a method as async any exceptions are stored in the returned task (both from the asynchronous part and the synchronous one) and thrown only when the task is awaited (or waited). When it's not async, the exceptions from the synchronous parts act just like in any other method.
My suggestion: Use the second one for the added performance boost but keep an eye out for exceptions and bugs.
An example that shows the difference:
public static async Task Test()
{
Task pending = Task.FromResult(true);
try
{
pending = SendAsync1();
}
catch (Exception)
{
Console.WriteLine("1-sync");
}
try
{
await pending;
}
catch (Exception)
{
Console.WriteLine("1-async");
}
pending = Task.FromResult(true);
try
{
pending = SendAsync2();
}
catch (Exception)
{
Console.WriteLine("2-sync");
}
try
{
await pending;
}
catch (Exception)
{
Console.WriteLine("2-async");
}
}
public static async Task SendAsync1()
{
throw new Exception("Sync Exception");
await Task.Delay(10);
}
public static Task SendAsync2()
{
throw new Exception("Sync Exception");
return Task.Delay(10);
}
Output:
1-async
2-sync
First of all, I don't think that the code in your example compiles. You need to remove the 'async' keyword from SendAsync2.
If you do that, then these methods can be used interchangeably, so no, there is no difference in this case. I would prefer the one without async/await.
However, there are cases where it would seem that there is no difference, but the difference lies in the details. Consider for example this code:
async Task<X> Get()
{
using (something)
{
return await GetX();
}
}
If you were to change this to:
Task<X> Get()
{
using (something)
{
return GetX();
}
}
then the using block no longer protects the execution encapsulated in x, and something will be disposed earlier than it would in the first case. Important for example when something is a Entity Framework context.
The same goes for return await inside try blocks.
Your first method which awaits will cause the compiler to create a state machine, since once the await keyword is hit the method will return to the caller, and once the awaited part is completed it has to resume from the point where it left off.
But, since you aren't doing anything after awaiting (there is no continuation), there is no need for that state machine.
The second method is preferred in this case, and you can omit the async keyword from it since you are not awaiting anything
I've been banging my head against a wall for two days now, and frankly I'm annoyed with myself because I just can't seem to get it.
I'm in a webapi context. During this request I need to send some data to one of our other systems, this system is slow to return, due to heavy calculations and multiple database saves etc etc. I need to log the result of this operation, regardless of whether it is successful or not. But I don't want to wait around for it to finish.
I've read that I should be async await all the way from top to bottom. I would have to convert numerous methods if I decided to do this, as I'm already 3 or 4 methods deep, which I fear would branch out even more.
What are my options here? If I go async await all the way down, what do I do with the methods higher up the stack, like my WebApi controllers?
Here is my code, I've tried to thin it down as much as I can. Right now I'm using Task.Result() in the method PushResult(). Which to my understanding is blocking the async? This code works in that the request gets sent. But the TestLog is always last, not first. Therefore not async.
//I'm in a public service and referenced twice
private void MyEndProcess()
{
// other stuff
_vendorPushService.PushResult(); // This could take a while and I have to wait for it!
_logService.PostLog(LogType.TestLog, "Test");
}
//I'm referenced above and somewhere else in the code base
public void PushResult()
{
ExternalResultModel externalResultModel = _resultService.GetExternalResultModel();
PushedResultModel pushedResult = new PushedResultModel();
try
{
pushedResult = _vendorRequestService.PushResultAsync(externalResultModel).Result;
}
catch (Exception ex)
{
pushedResult.Success = false;
}
if (pushedResult.Success)
{
_logService.PostLog(LogType.SuccessLog, pushedResult.Message);
}
else
{
_logService.PostLog(LogType.FailedLog, pushedResult.Message);
}
}
public async Task<PushedResultModel> PushResultAsync(ExternalResultModel externalResultModel)
{
// setup the requestMessage
HttpResponseMessage responseMessage = await _httpRequestService
.SendRequest(requestMessage)
.ConfigureAwait(false);
return new PushedResultModel
{
Success = responseMessage.IsSuccessStatusCode,
Message = await responseMessage.Content.ReadAsStringAsync()
};
}
public class HttpRequestService : IHttpRequestService
{
private readonly HttpClient _httpClient;
public HttpRequestService(IHttpClientAccessor httpClientAccessor)
{
_httpClient = httpClientAccessor.HttpClient;
}
public async Task<HttpResponseMessage> SendRequest(HttpRequestMessage requestMessage)
{
HttpResponseMessage httpResponseMessage = await _httpClient.SendAsync(requestMessage).ConfigureAwait(false);
return httpResponseMessage;
}
}
You should implement async await all the way from top to bottom.
If I go async await all the way down, what do I do with the methods higher up the stack, like my WebApi controllers?
Just make your controller actions async like this:
[RoutePrefix("api")]
public class PresidentsController : ApiController
{
[Route("presidents")]
public async Task<IHttpActionResult> GetPresidents()
{
await Task.Delay(TimeSpan.FromSeconds(10)).ConfigureAwait(false);
return Ok();
}
}
It's easiest way to implement async methods. Even if it will add some work to change everything to async it will benefit in future, because You will avoid many problem with async code.
If you absolutly HAVE to use async method in synchronous methods make it block in ONE place, like this:
public void MySyncMethod()
{
try
{
this.MyAsyncMethod().Wait();
}
catch (Exception exception)
{
//omited
}
}
private async Task MyAsyncMethod()
{
await AsyncLogic().ConfigureAwait(false);
}
But i don't recommend it. You should just use async await all the way to controller action.
In your comment you said you want to process a task in the background and not make the client calling your API wait. To do that, you don't really need to use async/await.
Try this:
private void MyEndProcess()
{
// other stuff
Task.Run(_vendorPushService.PushResult()).ConfigureAwait(false); //fire and forget
_logService.PostLog(LogType.TestLog, "Test");
}
The Task.Run will start the task, and the ConfigureAwait(false) tells it that it does not need to resume on the same context that we're currently on (meaning that the context can close before the task is finished - i.e. the response can be sent back without waiting for the task to finish).
You will get a compiler warning that you're not awaiting Task.Run, but that's what you want.
Keep in mind that when you do this, HttpContext.Current will not be available inside PushResult.
I have an xUnit (2.1.0) test that always hangs/deadlocks. Here the code with the names of classes/methods changed for clarity and confidentiality:
[Fact]
public void DocumentModificationTest()
{
Exception ex = null;
using (TestDependency testDependency = new TestDependency())
{
TestDependencyDocument testDependencyDoc = testDependency.Document;
MockTestDependency fakeDependency = new MockTestDependency();
try
{
DoStuffToTheDocument(testDependencyDoc, "fileName.doc", fakeDependency);
}
catch (Exception e)
{
ex = e;
}
}
Assert.Null(ex);
}
If I set a breakpoint and step over until the assert I can see that ex is null and the test should pass and be done with, but it just hangs and I never see Test Successful on the runner.
Here's what DoStuffToTheDocument looks like:
public static void DoStuffToTheDocument(TestDependencyDocument document, string pFileName, MockTestDependency pContainer)
{
pContainer.CheckInTheDocFirst(async () =>
{
//check some stuff
//test returns early here
//check other stuff(test never gets here)
//await method (thus the async anonymous method)
});
}
And lastly here's what CheckInTheDocFirst looks like:
public void CheckInTheDocFirst(Action pConfirmAction)
{
pConfirmAction(); //since this is a method in a mock class only used for testing we just call the action
}
Any ideas whats happening here? Is there something with my async-await paradigm that is causing this test to hang?
It turns out that this is an issue caused by async void test method support in xUnit: https://github.com/xunit/xunit/issues/866#issuecomment-223477634
While you really should carry async all the way up, sometimes this isn't feasible because of interoperability concerns. You can't always change the signatures of everything you're working with.
One thing to note about your assert, however, is that it will always prove true even if there's an exception thrown in the async void method (the lambda, in this case). This is because exception handling is different for async void:
Async void methods have different error-handling semantics. When an exception is thrown out of an async Task or async Task method, that exception is captured and placed on the Task object. With async void methods, there is no Task object, so any exceptions thrown out of an async void method will be raised directly on the SynchronizationContext that was active when the async void method started. Figure 2 illustrates that exceptions thrown from async void methods can’t be caught naturally.
When you have an async function, you should really be async all the way down. Otherwise you run into issues with sync contexts being blocked which will result in lockups.
pContainer.CheckInTheDocFirst should be async and return a Task (since it's taking an async function that returns a Task object).
DoStuffToDocument should be an async function that returns a Task, since it calls an async function.
And finally, the test itself should also be an async method that returns a task.
If you run the async all the way up the stack, I think you'll find things just work.
I need to implement a custom Storage provider for aspnetidentity.
I had a good look round and i found quite a few.However they seem all wrong to me.
My understing is that if you have a method that ends with "async" than it should by asynchronous.
See example taken from somebody's code and this is scattered all over the place.
I find below very misleading since it's not Async at all from what I can see:
public Task<TUser> FindByIdAsync(int userId)
{
TUser result = userTable.GetUserById(userId) as TUser; //this is not async
if (result != null)
{
return Task.FromResult<TUser>(result);
}
return Task.FromResult<TUser>(null);
}
should this be coded like this?:
public async Task<TUser> FindByIdAsync(int userId)
{
TUser result = userTable.GetUserByIdAsync(userId) as TUser;
if (result != null)
{
return await Task.FromResult<TUser>(result);
}
return await Task.FromResult<TUser>(null);
}
Questions?
Is it correct to do "Task.FromResult"? What I mean is does "Task.FromResult actually turns into synchronous? what should it be?
What is the correct way to code the above? what about configureAwait(false)
should async be "All the way down including datalayer to avoid deadlocking"
any sample code /snippet would be appreciated
many thanks for any feedback
The code is not misleading. ASP.NET Identity framework has been designed to provide an asynchronous interface by returning a Task and indicating this by adding the Async suffix to the method name:
Task<TUser> FindByIdAsync(int userId)
However, the underlying provider may not have asynchronous methods. In that case you cannot create an asynchronous implementation but you still have to implement the interface and to do that will have use Task.FromResult exactly as it is done in your first code snippet.
Implementing an asynchronous method using synchronous code
public Task<TUser> FindByIdAsync(int userId)
{
TUser result = userTable.GetUserById(userId) as TUser;
return Task.FromResult<TUser>(result);
}
If your underlying provider supports asynchronous methods you should use async and await.
Implementing an asynchronous method using asynchronous code
public async Task<TUser> FindByIdAsync(int userId)
{
TUser result = (await userTable.GetUserByIdAsync(userId)) as TUser;
return result;
}
Note that Task.FromResult is not used. Task.FromResult is only needed when you have a TResult created by synchronous code and you have to convert it to Task<TResult> required by asynchronous code.
Sometimes your underlying provider can return the desired Task<TUser> without any further work. In that case you can remove the async and await and still provide an asynchronous implementation. This can result in slightly more efficient code:
public Task<TUser> FindByIdAsync(int userId)
{
Task<TUser> result = userTable.GetUserByIdAsync(userId);
return result;
}
The initial code is definitely not asynchronous. It looks like it was put that way to cope with an API design.
However the proposed change doesn't look async to me either. Task.FromResult just creates a completed task with a result, doesn't make anything asynchronous or executes any kind of awaitable code so you should not await on it.
In your case, assuming GetUserByIdAsync returns a Task<TUser>, and assuming the whole purpose of this code (as it seems) is to always return a completed task (never faulted or cancelled), this could be rewritten as:
public async Task<TUser> FindByIdAsync(int userId)
{
var tResult = userTable.GetUserByIdAsync(userId);
TUser result = null;
try
{
result = await tResult;
}
except
{
// Bad idea, but here goes to your first snippet
}
return Task.FromResult<TUser>(result);
}
Note: this is a bad idea as #PanagiotisKanavos commented, it's hiding a possibly faulted state and you won't ever know if your null result came the user not being found, or if there was an error condition: I'd avoid it.
If a faulted/cancelled state is valid, this could simply be:
public Task<TUser> FindByIdAsync(int userId)
{
return userTable.GetUserByIdAsync(userId);
}
An async method is a way for the compiler to build something that will return a promise our future. In the case of the .NET Framework and C#, that is a Task.
The await instruction takes any awaitable and Task just happens to be one. It doesn't know or care if the method/operations being invoked is really asynchronous or not.
Task.FromResult<T> returns a completed task and if you use it in an await instruction inside an async method it will be considered to have been completed synchronously and execution will continue.
So, using async and await with just calls to Task.FromResult<T> ends up just being a waste of CPU cycles and memory by the compiler generating code that will waste more CPU cycles and memory at run time.
Because an async method always returns a Task a decision was made to make it implicit to improve readability and give it some kind of sync feeling. The compile will wrap the return value in a Task. That's why you can't return Task.FromResult<TUser>(result) or Task.FromResult<TUser>(null) directly and are awaiting it to get the value.
So, the async equivalent of your synchronous code would be:
public async Task<TUser> FindByIdAsync(int userId)
{
var result = await userTable.GetUserByIdAsync(userId) as TUser;
if (result != null)
{
return result;
}
return null;
}
Or:
public async Task<TUser> FindByIdAsync(int userId)
{
return await userTable.GetUserByIdAsync(userId) as TUser;
}
I'm currently trying to write async code and I have the feeling that my code is not too correct at all.
I have the following method:
public void Commit()
{
_context.SaveChangesToDatabase();
}
Don't judge the code here as this are only samples. Also, don't say that if I'm using Entity Framework, that they come packaged with Async methods already. I just want to understand the async concept here.
Let's say that the method SaveChangesToDatabase does takes seconds to complete.
Now, I don't want to wait for it so I create an async method:
public async Task CommitAsync()
{
await Task.Run(() => Commit());
}
Does this mean that if I have a method:
public void Method()
{
// Operation One:
CommitAsync();
// Operation Two.
}
Does this mean that my code on Operation two will be executed before CommitAsync() is even completed?
If not, please guide me in the right direction.
Update
Based on the remarks here that I'm ignoring my async method results, is this implementation better?
public Task<TaskResult> CommitAsync()
{
var task = new Task<TaskResult>(() =>
{
try { Commit(); }
catch (Exception ex)
{
return new TaskResult
{
Result = TaskExceutionResult.Failed,
Message = ex.Message
};
}
return new TaskResult { Result = TaskExceutionResult.Succeeded };
});
task.Start();
return task;
}
This does mean that I need to put the async modifier on the method that call this code so that I can await this which means continue with the current execution and return when this method has been completed.
Fire but don't forget
CommitAsync() returns a Task, but Method ignores the return value of CommitAsync completely -- so yes, the code will not wait but simply go on with what's after that. This is bad, because, if Commit() throws an exception, you will never see it. Ideally, every task should be waited on somewhere by someone, so you can at least see if it fails.
Let's say that you have no async alternative to SaveChangesToDatabase, but you'd like to use it in an async context anyway. You can use Task.Run to create a "fake-asynchronous" method, but this is not recommended (see below):
public Task CommitAsync() {
return Task.Run(() => Commit());
}
And then, assuming Method is doing something interesting with async (which the below code does not do since it's the only asynchronous operation in there):
public async Task MethodAsync() {
// Operation One:
await CommitAsync();
// Operation Two.
}
Assuming you do not want to wait, but you do want to do something if the task failed, you can use a separate method:
public void Method() {
// Operation One:
var _ = TryCommitAsync();
// Operation Two.
}
private async Task TryCommitAsync()
{
try
{
await CommitAsync();
}
catch (Exception ex)
{
Console.WriteLine(
"Committing failed in the background: {0}",
ex.Message
);
}
}
Getting back results
Let's suppose .Commit() does return something (like the number of records affected); a similar "fake-asynchronous" wrapper (again, not recommended - see below) would look like this:
public Task<int> CommitAsync() {
return Task.Run(() => Commit());
}
If you want this result, you can await the task immediately:
public async Task MethodAsync() {
// Operation One:
int recordsAffected = await CommitAsync();
// Operation Two.
}
Or, if you don't need it immediately, use await when you do:
public async Task MethodAsync() {
// Operation One:
Task<int> commit = CommitAsync();
// Operation Two.
// At this point I'd really like to know how many records were committed.
int recordsAffected = await commit;
}
Async: don't fake it
In general, you don't want to write wrappers like CommitAsync() because they mislead callers into thinking code will be asynchronous when it isn't really, which brings few benefits other than not blocking (which is still useful in UI code, but not as good as true asynchronous code which doesn't need to use worker threads for everything). In other words, you should use Task.Run in the invocation of a method, not as the implementation of a method.
So don't, as a habit, write wrappers like CommitAsync for every synchronous method you have -- instead you want to make a true CommitAsync that uses the async support of the underlying libraries/frameworks (SqlCommand.ExecuteReaderAsync(), etcetera.)
If you have no choice and must use Task.Run, then the appropriate usage would look more like:
// This method is in the UI layer.
public async Task MethodAsync() {
// Operation One:
// Commit() is a method in the DA layer.
await Task.Run(() => Commit());
// Operation Two.
}
Here
http://channel9.msdn.com/events/TechEd/NorthAmerica/2013/DEV-B318#fbid=
is a good explanation on how to work with async, and why you should avoid "async over sync", which is what you are doing now with
public Task CommitAsync() {
return Task.Run(() => Commit());
}
There are some scenarios where you can benefit from it, but if you are going to provide this as part of a library is NOT a good idea to make this.
If this code is ONLY and ONLY going to be used by your app, and you are sure what you are doing and dont have a wawy to call async methods inside your async method, just do it