Does GetAwaiter() throw a single exception? [duplicate] - c#

This question already has answers here:
Is Task.Result the same as .GetAwaiter.GetResult()?
(7 answers)
Closed 3 years ago.
I am trying to understand why the following Task.Run and GetAwaiter().GetResult() would be used instead of await ... <result>
(var success, var response) = Task.Run(() => HTTPHelper.SendRequest<SomeJsonResponse>( ... )).GetAwaiter().GetResult();
Does the code above throw, as this article shows, an Exception and not an AggregateException? If so, I believe that is why this structure was chosen.
Is it possible to use async ... await in this situation and have the same result? (I assume not, if the single exception requirement is only possible with the code above.)

Yeah, you can and should use async await :
(var success, var response) = await HTTPHelper.SendRequest<SomeJsonResponse>( ... )
Then there is no need to wrap it into the Task. I assume .SendRequest<SomeJsonResponse>() returns the Task.
FYI: .Wait(), .Result or GetAwaiter().GetResult() are all thread blocking executions

Related

How to wrap a synchronous function to async function in C#? [duplicate]

This question already has an answer here:
Awaiting a Callback method
(1 answer)
Closed 1 year ago.
am using a synchronous 3rd function which I cannot modify, such as:
public void startDoSth(Action<string> onDone)
startDoSth spawn a new thread to do the job, and returns immediately, and when the thing is done, my onDone function would be called.
I'd like to write an asynchronous method like below to wrap it:
public async Task<string> doSthAsync();
So, someone can call it like this:
string s = await doSthAsync()
onDone(s)
In doSthasync() I call startDoSth() to do the real thing.
But I have no idea how to write the doSthAsync().
Could anyone tell if it is possible and how to do it? Thanks a lot.
You can use TaskCompletionSource to convert that into TAP:
Task<string> DoSthAsync()
{
var tcs = new TaskCompletionSource<string>();
startDoSth(tcs.SetResult);
return tcs.Task;
}
SetResult completes the returned Task (and sets the result), so that can be passed as the callback function.

UI Received task got cancelled [duplicate]

This question already has answers here:
'await' works, but calling task.Result hangs/deadlocks
(6 answers)
Closed 3 years ago.
In my application, I am trying to update the user profile which calls the Rest API. API has one sync method UpdateProfile where execution getting stuck.
this line of code is ending the execution
command.UserProfile.LookupItems = GetLookupItemsByUserId(existingUser.Id).Result;
When i changed this line of code to
command.UserProfile.LookupItems = Task.Run(async () => await GetLookupItemsByUserId(existingUser.Id)).Result;
It started working without any issue.Can anybody explain to me what is going on behind the scene?
The first version is blocking the current thread, when the task complete the blocked thread cannot catch it.
YourType Signature() {
var neverUsedValue = task.Result;
}
The second one is yielding the current "thread" until the task is returned.
YourType Signature() {
var value = Task.Run(await => async MethodThatWillComplete()).Result
}
What you should do is propagate the async to the method:
async Task<YourType> SignatureAsync() {
command.UserProfile.LookupItems = await GetLookupItemsByUserId(existingUser.Id);
}
In this way you will avoid handling the AggregateException.
There is very well written article on this here:Don't block async
In a few words, blocking on async code is bad because it may be blocking the thread which is supposed to run the async code and thus generete a deadlock.

After Task.IsCompleted what is better: await or Result [duplicate]

This question already has answers here:
Await on a completed task same as task.Result?
(2 answers)
Is there a difference between calling .Result or await on known completed tasks? [duplicate]
(1 answer)
Closed 3 years ago.
I'm working in a simple timeout code for my http requests. I got this
private async Task<HttpResponseMessage> ExecuteIOTask(Task<HttpResponseMessage> ioTask, int timeout)
{
var timeoutTask = await Task.WhenAny(Task.Delay(timeout), ioTask);
if (ioTask.IsCompleted)
return ioTask.Result;
throw new TimeoutException();
}
After IsCompleted, is there any difference using Result vs await ? The task is already completed at that instance, so I think the performance should be the same. But i'm a little concern about the exception handling. I think Result is not going to propagate the exceptions but await will.
Is this correct?
Do not use .Result, always use await.
Please note that .Result can cause deadlocks and can cause some unpredictable behaviors in the applications.
The only way then would be to take the process dump and then analyze dump in procdump. Believe me it is going to be very difficult debugging.
Please find best practices about async programming at this blog.
As far as exception handling is concerned, it is mentioned in this blog that:
Every Task will store a list of exceptions. When you await a Task, the
first exception is re-thrown, so you can catch the specific exception
type (such as InvalidOperationException). However, when you
synchronously block on a Task using Task.Wait or Task.Result, all of
the exceptions are wrapped in an AggregateException and thrown.
Hope this helps.

Asynchronous calls with await [duplicate]

This question already has answers here:
How Async and Await works
(4 answers)
Closed 7 years ago.
I have one question about await keyword. Here is some test code:
string username = await GetUsernameAsync();
// Some other code
var some_variable = username;
My question is: Does waiting starts at first line where we called async method or at the third line where we need the result of async method? Does some other code executes after GetUsernameAsync finishes its execution, or they are executing in parallel?
It happens at the line where the await is.
If you want to delay the waiting, move the await to the moment you need the result. Remember the task, and move on. Then if you need the result, await the task:
Task<string> usernameTask = GetUsernameAsync();
// Some other code
var some_variable = await usernameTask;
The first one. Take into account the await is just sugar syntax. It will be, more or less, replaced by a Task.Wait() to obtain the result. In fact, GetUsernameAsync() will return a Task, not a string.
Take a look to this link to deep more how threads work with the asyn/await pattern

What is the difference between WaitAll and WhenAll? [duplicate]

This question already has answers here:
WaitAll vs WhenAll
(4 answers)
Closed 6 years ago.
I have this code:
List<ComponentesClasificaciones> misClasificaciones = new List<ComponentesClasificaciones>();
Task tskClasificaciones = Task.Run(() =>
{
misClasificaciones = VariablesGlobales.Repositorio.buscarComponentesClasificacionesTodosAsync().Result;
});
Task.WhenAll(tskClasificaciones);
List<ComponentesClasificaciones> misVClasificacionesParaEstructuras = new List<ComponentesClasificaciones>(misClasificaciones);
If I use Task.WhenAll, misClasificaciones does not have any element but when I use awit all I get all the elements that I request to the database.
When to use WhenAll and when to use WaitAll?
MSDN does a good job of explaining this. The difference is pretty unambiguous.
Task.WhenAll:
Creates a task that will complete when all of the supplied tasks have completed.
Task.WaitAll:
Waits for all of the provided Task objects to complete execution.
So, essentially, WhenAll gives you a task that isn't done until all of the tasks you give it are done (and allows program execution to continue immediately), whereas WaitAll just blocks and waits for all of the tasks you pass to finish.
WhenAll returns a task that you can ContinueWith once all the specified tasks are complete. You should be doing
Task.WhenAll(tskClasificaciones).ContinueWith(t => {
// code here
});
Basically, use WaitAll when you want to synchronously get the results, use WhenAll when you want to start a new asynchronous task to start some more processing

Categories