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.
Related
This question already has answers here:
.NET Core equivalent to Thread.Abort
(8 answers)
What's wrong with using Thread.Abort()
(7 answers)
Closed last month.
Is it possible to abort a synchronous method that executes for a long time?
I have the method Test that calls the LongRunningMethod method that consumes a lot of memory and CPU, in case it lasts longer than 30 seconds, I want to abort it. However, after an exception is thrown, the CPU and memory are still increasing, although the task is completed.
Code:
static async Task<string> Test (string input)
{
var tokenSource = new CancellationTokenSource();
var task = LongRunningMethod(input, tokenSource.Token)
.WaitAsync(TimeSpan.FromSeconds(30));
try
{
var result = await task;
return result;
}
catch (Exception ex)
{
// if the timeout is thrown, the LongRunningMethod still executes in background
// and increase memory and CPU
}
}
static Task<string> LongRunningMethod(string input, CancellationToken token)
{
var task= Task.Run(() =>
{
SynchronousMethodThatConsumesMemoryAndCpu(input);
return "end";
},
token);
return task;
}
I don't want to optimize it or write it differently, I am asking if it is possible to abort the execution of that method if I cannot pass CancellationToken.
No, there isn't. There is no official helper method or other mechanism for cancelling/aborting a method which doesn't provide a mechanism to cancel/abort (e.g. accepting a token).
In addition, in a comment from March 2022 to Proposal for non-cooperative abortion of code execution #66480 the Microsoft's .NET performance guru Stephen Toub who has written many times about tasks and threads says:
We've deleted a whole bunch of code in .NET Core that was there to help try to improve reliability in the face of thread aborts (...)
New code has also been written assuming no thread aborts. (...)
This means that tricks with Thread.Interrupt are now even more dangerous.
It looks that you you would have to:
Run the method in a separate process; or
Let the method run to completion and just ignore its results if the 30 seconds have passed.
This question already has answers here:
How and when to use ‘async’ and ‘await’
(25 answers)
How do yield and await implement flow of control in .NET?
(5 answers)
Brief explanation of Async/Await in .Net 4.5
(3 answers)
Closed 2 years ago.
I never had a good chance to go deep into async/await , so I have just a gist of what it does.
So I tried it in WinForms app like this:
private async void button2_Click(object sender, EventArgs e)
{
// In below line I understand the Task is created and scheduled to execute, which in this
// simple case means, that it executes right away asynchronously.
var task = Task.Factory.StartNew(() =>
{
Task.Delay(5000).Wait();
return 12;
});
// Here we wait for the task to finish, so we don't see MessageBox yet.
var res = await task;
MessageBox.Show("Result is :" + res);
}
My question is, since we are waiting on await I expected to block UI thread, since we can go any further in that thread (to the line with MessageBox). So UI thread actually stops on method with event hadnler.
But, to my surprise, windows is responsive and everything works very well, but I didn't expect that. Can anybody explain me what is going on?
After reading this post, I still have a doubt, if await is asynchronous and doesn't block UI thread in my example, why the thread doesn't proceed to next line with MessageBox? How the UI thread proceeds then?
Is good idea that code after await is just another Task, like in ContinueWith? But it comes back to UI context?
Async methods are a lot like generator methods. The compiler will split up your code at each await operator. A block of code is inserted to check if the task is already complete, in which case the method immediately continues. Or if the task is not complete, a callback is registered to continue execution later, and your method returns.
Returning early is the whole point of an async method.
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
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.
This question already has answers here:
Catch an exception thrown by an async void method
(6 answers)
Closed 9 years ago.
I have a simplistic structure and I have a hard time understanding why it works (or does not work) how I think it should work.
Basically, there are two methods
private async void DoStuff()
{
try {
AuthenticationStuff();
}catch(UnauthorizedAccessException){
UI.Display("AMAGAD!");
}
}
private async void AuthenticationStuff()
{
var user = GetUser();
if(user == null) throw new UnauthorizedAccessException();
DoMoreAuthenticationStuff();
}
Now the problem is that the exception never reaches DoStuff() method's handler. My first instinct was that "hey, it's an async method, I have to await it", but I can't do that either as apparently async void is different from async Task<void>.
I am trying to understand what's going on in here. Why isn't the exception going to the handler, but instead the debugger breaks at "DoMoreAuthenticationStuff()" with an unhandeled exception error?
Exceptions raised by an async void method go directly to the SynchronizationContext that was active at the time the method started. This is one of the reasons why you should avoid async void. I cover this and other reasons in my MSDN article Best Practices in Asynchronous Programming.
To catch exceptions like this, change your async void method to async Task and await the returned task.
My first instinct was that "hey, it's an async method, I have to await
it", but I can't do that either as apparently async void is different
from async Task.
You can just say async Task MyMethod(). Then you can await its result to propagate the exception (and to wait for completion).
Also observe Stephen Cleary's answer for more details.