task result hangs c#

Await, and UI, and deadlocks! Oh my!

Stephen Toub - MSFT

January 13th, 2011 2 3

It’s been awesome seeing the level of interest developers have had for the Async CTP and how much usage it’s getting.  Of course, with any new technology there are bound to be some hiccups.  One issue I’ve seen arise now multiple times is developers accidentally deadlocking their application by blocking their UI thread, so I thought it would be worthwhile to take a few moments to explore the common cause of this and how to avoid such predicaments.

At its core, the new async language functionality aims to restore the ability for developers to write the sequential, imperative code they’re used to writing, but to have it be asynchronous in nature rather than synchronous.  That means that when operations would otherwise tie up the current thread of execution, they’re instead offloaded elsewhere, allowing the current thread to make forward progress and do other useful work while, in effect, asynchronously waiting for the spawned operation to complete.  In both server and client applications, this can be crucial for application scalability, and in client applications in particular it’s also really useful for responsiveness.

Most UI frameworks, such as Windows Forms and WPF, utilize a message loop to receive and process incoming messages.  These messages include things like notifications of keys being typed on a keyboard, or buttons being clicked on a mouse, or controls in the user interface being manipulated, or the need to refresh an area of the window, or even the application sending itself a message dictating some code to be executed.  In response to these messages, the UI performs some action, such as redrawing its surface, or changing the text being displayed, or adding items to one of its controls., or running the code that was posted to it.  The “message loop” is typically literally a loop in code, where a thread continually waits for the next message to arrive, processes it, goes back to get the next message, processes it, and so on.  As long as that thread is able to quickly process messages as soon as they arrive, the application remains responsive, and the application’s users remain happy.  If, however, processing a particular message takes too long, the thread running the message loop code will be unable to pick up the next message in a timely fashion, and responsiveness will decrease.  This could take the form of pauses in responding to user input, and if the thread’s delays get bad enough (e.g. an infinite delay), the application “hanging”.

In a framework like Windows Forms or WPF, when a user clicks a button, that typically ends up sending a message to the message loop, which translates the message into a call to a handler of some kind, such as a method on the class representing the user interface, e.g.:

private void button1_Click(object sender, RoutedEventArgs e) {     string s = LoadString();     textBox1.Text = s; }

Here, when I click the button1 control, the message will inform WPF to invoke the button1_Click method, which will in turn run a method LoadString to get a string value, and store that string value into the textBox1 control’s Text property.  As long as LoadString is quick to execute, all is well, but the longer LoadString takes, the more time the UI thread is delayed inside button1_Click, unable to return to the message loop to pick up and process the next message.

To address that, we can choose to load the string asynchronously, meaning that rather than blocking the thread calling button1_Click from returning to the message loop until the string loading has completed, we’ll instead just have that thread launch the loading operation and then go back to the message loop.  Only when the loading operation completes will we then send another message to the message loop to say “hey, that loading operation you previously started is done, and you can pick up where you left off and continue executing.”  Imagine we had a method:

public Task<string> LoadStringAsync();

This method will return very quickly to its caller, handing back a .NET Task<string> object that represents the future completion of the asynchronous operation and its future result.  At some point in the future when the operation completes, the task object will be able to hand out the operations’ result, which could be the string in the case of successful loading, or an exception in the case of failure.  Either way, the task object provides several mechanisms to notify the holder of the object that the loading operation has completed.  One way is to synchronously block waiting for the task to complete, and that can be accomplished by calling the task’s Wait method, or by accessing its Result, which will implicitly wait until the operation has completed… in both of these cases, a call to these members will not complete until the operation has completed.  An alternative way is to receive an asynchronous callback, where you register with the task a delegate that will be invoked when the task completes.  That can be accomplished using one of the Task’s ContinueWith methods.  With ContinueWith, we can now rewrite our previous button1_Click method to not block the UI thread while we’re asynchronously waiting for the loading operation to complete:

private void button1_Click(object sender, RoutedEventArgs e) {     Task<string> s = LoadStringAsync();     s.ContinueWith(delegate { textBox1.Text = s.Result; }); // warning: buggy }

This does in fact asynchronously launch the loading operation, and then asynchronously run the code to store the result into the UI when the operation completes.  However, we now have a new problem.  UI frameworks like Windows Forms, WPF, and Silverlight all place a restriction on which threads are able to access UI controls, namely that the control can only be accessed from the thread that created it.  Here, however, we’re running the callback to update the Text of textBox1on some arbitrary thread, wherever the Task Parallel Library (TPL) implementation of ContinueWith happened to put it.  To address this, we need some way to get back to the UI thread.  Different UI frameworks provide different mechanisms for doing this, but in .NET they all take basically the same shape, a BeginInvoke method you can use to pass some code as a message to the UI thread to be processed:

private void button1_Click(object sender, RoutedEventArgs e) {     Task<string> s = LoadStringAsync();     s.ContinueWith(delegate     {         Dispatcher.BeginInvoke(new Action(delegate         {             textBox1.Text = s.Result;         }));     }); }

The .NET Framework further abstracts over these mechanisms for getting back to the UI thread, and in general a mechanism for posting some code to a particular context, through the SynchronizationContext class.  A framework can establish a current context, available through the SynchronizationContext.Current property, which provides a SynchronizationContext instance representing the current environment.  This instance’s Post method will marshal a delegate back to this environment to be invoked: in a WPF app, that means bringing you back to the dispatcher, or UI thread, you were previously on.  So, we can rewrite the previous code as follows:

private void button1_Click(object sender, RoutedEventArgs e) {     var sc = SynchronizationContext.Current;     Task<string> s = LoadStringAsync();     s.ContinueWith(delegate     {         sc.Post(delegate { textBox1.Text = s.Result; }, null);     }); }

and in fact this pattern is so common, TPL in .NET 4 provides the TaskScheduler.FromCurrentSynchronizationContext() method, which allows you to do the same thing with code like:

private void button1_Click(object sender, RoutedEventArgs e) {     LoadStringAsync().ContinueWith(s => textBox1.Text = s.Result,         TaskScheduler.FromCurrentSynchronizationContext()); }

As mentioned, this works by “posting” the delegate back to the UI thread to be executed.  That posting is a message like any other, and it requires the UI thread to go through its message loop, pick up the message, and process it (which will result in invoking the posted delegate).  In order for the delegate to be invoked then, the thread first needs to return to the message loop, which means it must leave the button1_Click method.

Now, there’s still a fair amount of boilerplate code to write above, and it gets orders of magnitude worse when you start introducing more complicated flow control constructs, like conditionals and loops.  To address this, the new async language feature allows you to write this same code as:

private async void button1_Click(object sender, RoutedEventArgs e) {     string s = await LoadStringAsync();     textBox1.Text = s; }

For all intents and purposes, this is the same as the previous code shown, and you can see how much cleaner it is… in fact, it’s close to identical  in the code required to our original synchronous implementation.  But, of course, this one is asynchronous: after calling LoadStringAsync and getting back the Task<string> object, the remainder of the function is hooked up as a callback that will be posted to the current SynchronizationContext in order to continue execution on the right thread when the loading is complete.  The compiler is layering on some really helpful syntactic sugar here.

Now things get interesting. Let’s imagine LoadStringAsync is implemented as follows:

static async Task<string> LoadStringAsync() {     string firstName = await GetFirstNameAsync();     string lastName = await GetLastNameAsync();     return firstName + ” ” + lastName; }

LoadStringAsync is implemented to first asynchronously retrieve a first name, then asynchronously retrieve a last name, and then return the concatenation of the two.  Notice that it’s using “await”, which, as pointed out previously, is similar to the aforementioned TPL code that uses a continuation to post back to the synchronization context that was current when the await was issued.  So, here’s the crucial point: for LoadStringAsync to complete (i.e. for it to have loaded all of its data and returned its concatenated string, completing the task it returned with that concatenated result), the delegates it posted to the UI thread must have completed.  If the UI thread is unable to get back to the message loop to process messages, it will be unable to pick up the posted delegates that resulted from the asynchronous operations in LoadStringAsync completing, which means the remainder of LoadStringAsync will not run, which means the Task<string> returned from LoadStringAsync will not complete.  It won’t complete until the relevant messages are processed by the message loop.

With that in mind, consider this (faulty) reimplementation of button1_Click:

private void button1_Click(object sender, RoutedEventArgs e) {     Task<string> s = LoadStringAsync();     textBox1.Text = s.Result; // warning: buggy }

There’s an exceedingly good chance that this code will hang your application.  The Task<string>.Result property is strongly typed as a String, and thus it can’t return until it has the valid result string to hand back; in other words, it blocks until the result is available.  We’re inside of button1_Click then blocking for LoadStringAsync to complete, but LoadStringAsync’s implementation depends on being able to post code asynchronously back to the UI to be executed, and the task returned from LoadStringAsync won’t complete until it does.  LoadStringAsync is waiting for button1_Click to complete, and button1_Click is waiting for LoadStringAsync to complete. Deadlock!

This problem can be exemplified easily without using any of this complicated machinery, e.g.:

private void button1_Click(object sender, RoutedEventArgs e) {     var mre = new ManualResetEvent(false);     SynchronizationContext.Current.Post(_ => mre.Set(), null);     mre.WaitOne(); // warning: buggy }

Here, we’re creating a ManualResetEvent, a synchronization primitive that allows us to synchronously wait (block) until the primitive is set.  After creating it, we post back to the UI thread to set the event, and then we wait for it to be set.  But we’re waiting on the very thread that would go back to the message loop to pick up the posted message to do the set operation.  Deadlock.

The moral of this (longer than intended) story is that you should not block the UI thread.  Contrary to Nike’s recommendations, just don’t do it.  The new async language functionality makes it easy to asynchronous wait for your work to complete.  So, on your UI thread, instead of writing:

Task<string> s = LoadStringAsync(); textBox1.Text = s.Result; // BAD ON UI

you can write:

Task<string> s = LoadStringAsync(); textBox1.Text = await s; // GOOD ON UI

Or instead of writing:

Task t = DoWork(); t.Wait(); // BAD ON UI
Task t = DoWork(); await t; // GOOD ON UI

This isn’t to say you should never block.  To the contrary, synchronously waiting for a task to complete can be a very effective mechanism, and can exhibit less overhead in many situations than the asynchronous counterpart.  There are also some contexts where asynchronously waiting can be dangerous. For these reasons and others, Task and Task<TResult> support both approaches, so you can have your cake and eat it too.  Just be cognizant of what you’re doing and when, and don’t block your UI thread.

(One final note: the Async CTP includes the TaskEx.ConfigureAwait method.  You can use this method to suppress the default behavior of marshaling back to the original synchronization context.  This could have been used, for example, in the LoadStringAsync method to prevent those awaits from needing to return to the UI thread.  This would not only have prevented the deadlock, it would have also resulted in better performance, because we now no longer need to force execution back to the UI thread, when nothing in that method actually needed to run on the UI thread.)

Stephen Toub - MSFT Partner Software Engineer, .NET

Discussion is closed. Login to edit/delete existing comments.

I must admin that this article(and the series of articles you have written on TPL) is one of the most comprehensive blogs I have ever read regarding TPL.

I have one quick question regarding this statement that you have made:

There’s an exceedingly good chance that this code will hang your application. The Task.Result property is strongly typed as a String, and thus it can’t return until it has the valid result string to hand back; in other words, it blocks until the result is available. We’re inside of button1_Click then blocking for LoadStringAsync to complete, but LoadStringAsync’s implementation depends on being able to post code asynchronously back to the UI to be executed, and the task returned from LoadStringAsync won’t complete until it does. LoadStringAsync is waiting for button1_Click to complete, and button1_Click is waiting for LoadStringAsync to complete. Deadlock!

So the main problem as to why Deadlock occurs is because the UI Thread cannot process the message posted to the message pump right? Or is it because LoadStringAsync() method cannot even post message to the message pump because the UI thread is blocked by the caller waiting for LoadStringAsync() to complete. If my understanding is correct, the DeadLock happens because the UI thread cannot process the message posted to the message pump which means that LoadStringAsync did post to the message pump but that message cannot be picked up by the UI thread(as its waiting) and thus LoadStringAsync cannot mark itself as complete?

Microsoft employee

> So the main problem as to why Deadlock occurs is because the UI Thread cannot process the message posted to the message pump right?

Correct. The UI thread is blocked waiting for the task to complete, and the task won’t complete until the UI thread pumps messages, which won’t happen because the UI thread is blocked.

light-theme-icon

LeanSentry Robot

LeanSentry Diagnostics guide

Diagnose async hangs in asp.net core, mvc and webapi.

Diagnose async hangs in ASP.NET Core, MVC and WebAPI applications, using the async analysis inside LeanSentry Hang diagnostics.

Many modern ASP.NET applications are developed using the asynchronous task pattern. This pattern helps reduce the thread pool exhaustion issues traditionally associated with synchronous applications.

That said, async ASP.NET applications can and do still experience hangs!

Worse yet, hangs in async applications can be WAY harder to diagnose, because blocking asynchronous tasks have no readily apparent “stacks” showing where the code is blocked.

In this how-to, we’ll look at how to use LeanSentry Hang diagnostics to diagnose and fix async hangs.

What is an async hang?

An async hang is simply a hang that takes place in an asynchronous application, e.g. an application using the async/await pattern . From the standpoint of your website users, the symptoms are the same:

Requests queueing up during a hang (InetMgr.exe)

  • Your website is not responding/loading very slowly.

You can read more about identifying and diagnosing hangs in our Diagnose IIS website hangs guide.

What is the difference between an async hang and a synchronous hang?

In a synchronous application, a hang is almost always associated with a number of threads becoming blocked in synchronous application code. As a result, if inspecting the hang under a debugger, you can observe those threads and identify the stack traces where blockage is taking place:

Threads blocked during a hang (LeanSentry Hang diagnostics)

You can then inspect the blocked threads to identify where the code is becoming blocked, for example:

Thread stack of a synchronous hang (LeanSentry Hang diagnostics)

What separates an async hang from a traditional hang, is that it is caused by long-running or deadlocked asynchronous tasks. Because tasks are asynchronous, there are no blocked threads associated with them, and therefore we don’t know where the code is blocked!

No threads are blocked during an async hang

Diagnosing async hangs with LeanSentry Hang diagnostics

We’ve recently added asynchronous hang analysis to LeanSentry Hang diagnostics. To learn how to find hang diagnosis reports in LeanSentry, see Identify website hangs in our LeanSentry Hang diagnostics guide.

When LeanSentry diagnoses a hang, it will also attempt to analyze the outstanding async tasks. It will then try to detect async tasks that appear to be blocking and thereby causing the hang:

Async tasks blocked during a hang (LeanSentry Hang diagnostics)

Even though an async task does not have a “stack trace” like a synchronously blocked thread does, LeanSentry attempts to obtain an async completion trace which helps identify the sequence of tasks that are waiting on the “blocked” task:

Async stack trace for a blocking task

This completion trace helps you identify key information to find the blocked application code:

  • The application level code that triggered the async operation.
  • The task that you are waiting on.

Finding the application code awaiting the blocking async task

In the above example, the async code that we are waiting on is coming from the “ArticleController.DownloadAll” method.

Because a method may trigger multiple async operations, the 0-indexed AWAIT #0 tag helps us locate the specific await statement in the code:

Locating the code issuing the async task

In other words, you can find the async operation the code is waiting on by finding the await statement in the method that correspondings to the AWAIT #N number shown in the stack trace.

Finding the blocking task being awaited

Because asynchronous applications can have very complex task chains, we may also need to know what actual part of the async operation we issued from OUR code is taking time to complete.

To determine this, we need to look at the last task in the completion stack trace. That is the actual task we are waiting on.

Chances are, this task will represent some internal operation deep in the .NET framework code, such as waiting for some network operation to complete. You’ll have to interpret it based on the task type and other tasks in the completion trace:

At times, you may be able to guess at what the operation is from other tasks that are waiting during the hang:

Asyn task dependency during a hang

You can often do this by reviewing the operations that your application code is making, and making a logical inference based on the tasks present in large quantities in the hang analysis.

Tracing the async tasks in application code

Exploring the async tasks during the hang

Just like you can visually explore the blocked threads during a regular hang, you can also explore the async task trees that are park of the async hang.

Async task analysis tab

You can then drill into the task trees found during the hang:

Async task analysis tree

For more power, you can also use the task type and async task state filters to filter down to specific types of tasks.

Async task filter

Async task type and state filters in the table.

For example, you can filter to tasks that are:

  • Request : tasks that are recognized as blocking a request.

(LeanSentry is able to determine these states better in .NET core applications, and will report less state information for legacy .NET framework applications due to inherent limitations.)

Hangs can be hard to troubleshoot in production.

Async hangs are even harder, due to the lack of stack traces associated with blocked threads in synchronous hangs.

You can use LeanSentry Hang diagnostics to help diagnose both sync and async hangs, using the new async/await analysis functionality.

For more information on troubleshooting production IIS and ASP.NET hangs, see LeanSentry Hang diagnostics .

More resources

Cannot use saas monitoring / need an on-premise solution, want to automate leansentry deployment in a cloud environment, need expert assistance with an urgent performance issue.

LeanSentry: Troubleshoot Windows Server, IIS, and ASP.NET like an expert

task result hangs c#

'await' works, but calling task.Result hangs/deadlocks in C#

In C#, using await is the recommended way to get the result of an asynchronous operation. When you use await , the current method is suspended until the awaited task completes, and control is returned to the caller. This allows other threads to continue executing while the asynchronous operation is in progress.

On the other hand, calling task.Result on an incomplete task can lead to a deadlock or hang. This is because task.Result blocks the current thread until the task completes, but if the task is being awaited by another thread, the awaited task may be waiting for the current thread to complete before it can continue. This results in a deadlock where both threads are waiting for each other to complete.

To avoid this deadlock, you should use await instead of task.Result to get the result of an asynchronous operation. Here's an example:

In this example, we have an asynchronous method called GetValueAsync that returns a Task<int> . The method simulates an asynchronous operation by waiting for 1 second before returning the value 42.

In the Main method, we call GetValueAsync using await to get the result of the asynchronous operation. The Main method is marked as async because it uses await , and it has a void return type because it is a console application.

By using await , the Main method is suspended until the GetValueAsync method completes, but the current thread is not blocked. When the asynchronous operation completes, the result is assigned to the result variable, and we print the result to the console.

"C# Task.Result vs await deadlock issue":

  • Code: Task<int> myTask = MyAsyncMethod(); int result = myTask.Result; // Causes potential deadlock
  • Description: Illustrates the common deadlock issue when using Task.Result on an asynchronous task.

"Avoiding deadlock with Task.ConfigureAwait(false) in C#":

  • Code: Task<int> myTask = MyAsyncMethod(); int result = myTask.ConfigureAwait(false).GetAwaiter().GetResult();
  • Description: Shows how to use ConfigureAwait(false) to avoid potential deadlocks when calling Task.Result .

"C# await vs Task.Result best practices":

  • Code: async Task<int> MyAsyncMethod() { // Your asynchronous logic return await SomeAsyncOperation().ConfigureAwait(false); }
  • Description: Provides best practices for using await instead of Task.Result to avoid deadlocks.

"Understanding Task.Run and Task.Result in C#":

  • Code: Task<int> myTask = Task.Run(() => SomeAsyncOperation()); int result = myTask.GetAwaiter().GetResult();
  • Description: Explores the usage of Task.Run and Task.Result and potential deadlock issues.

"AsyncContext.Run vs Task.Result in C#":

  • Code: int result = AsyncContext.Run(() => SomeAsyncOperation());
  • Description: Compares the usage of AsyncContext.Run with Task.Result and addresses potential deadlocks.

"C# async/await deadlock troubleshooting guide":

  • Code: Task<int> myTask = MyAsyncMethod(); try { int result = await myTask.ConfigureAwait(false); } catch (Exception ex) { // Handle exception }
  • Description: Provides a troubleshooting guide for identifying and handling deadlocks with async/await in C#.

"C# Task.Run deadlock prevention":

  • Description: Discusses potential deadlock prevention strategies when using Task.Run and Task.Result .

"C# Task.Wait vs await deadlock scenarios":

  • Code: Task<int> myTask = MyAsyncMethod(); myTask.Wait(); // Potential deadlock int result = myTask.Result;
  • Description: Explores potential deadlock scenarios when using Task.Wait and Task.Result with asynchronous tasks.

"CancellationToken with Task.Result in C#":

  • Code: Task<int> myTask = MyAsyncMethod(cancellationToken); int result = myTask.GetAwaiter().GetResult();
  • Description: Demonstrates handling cancellation tokens when using Task.Result to avoid deadlocks.

"C# Task.FromResult and Task.Result deadlock":

  • Code: Task<int> myTask = Task.FromResult(SomeSynchronousOperation()); int result = myTask.GetAwaiter().GetResult();
  • Description: Addresses potential deadlocks when using Task.FromResult with Task.Result .

session-timeout show prediction enums jqgrid product session registration codeigniter splash-screen

More C# Questions

  • DbContext Query performance poor vs ObjectContext
  • Check if a class is derived from a generic class in C#
  • How to add site-wide no-cache headers to an MVC app
  • How to create an optional DateTime parameter in C#?
  • Loop through "selected" Enum values in C#?
  • ASP.NET MVC EPPlus Download Excel File
  • Detect if deserialized object is missing a field with the JsonConvert class in Json.NET
  • How to determine browser window size on server side C#
  •   Previous
  • Next  

Mike Volodarsky's Blog

Azure, iis, asp.net, and leansentry, async await hangs in asp.net core, mvc and webapi.

task result hangs c#

Debugging async await hangs is hard!

When I first wrote the LeanSentry Hang diagnostics, most .NET web applications were developed using synchronous patterns.

Meaning, developers called long-blocking IO operations like SQL queries, remote web service calls and the like using the regular synchronous method signatures, which blocked the thread until they were completed.

This would of course frequently contribute to ASP.NET hangs, as threads became blocked on these synchronous operations. 

(Skip the story, go straight to our async await hang diagnostics guide)

On the bright side, debugging these hangs was pretty easy because once you got the stack trace of the blocked operation, it would clearly point out where the blockage was taking place.

LeanSentry Hang diagnostic showing a graph of blocked threads during a hang.

Back then, you COULD write asynchronous applications (using the APM pattern ), but to be honest the only async applications we normally saw were our own.

Async await hangs

Fast forward to now.

Many modern ASP.NET applications using ASP.NET core, as well as the ASP.NET MVC and WebAPI frameworks, are now developed with the new async await patterns.

This is great, because it allows developers to execute long-blocking operations without tying up a thread, and therefore often avoid thread pool exhaustion when things take longer.

Unfortunately, this does not mean that hangs were gone. 

(In fact, the async model introduced a whole slew of new issues including synchronization context lockups, async completion crashes (when an async task erroneously ties to complete to a request that’s already finished), and the like.)

Worse yet, if you did have an async hang, debugging it just became astronomically harder … because there are no longer any blocked thread stack traces to show you where the blockage takes place!

In an async hang, there are no blocked threads!

Instead, there are some long-running tasks somewhere in memory that are doing something, and they are generally nowhere to be seen.

LeanSentry async await diagnostics to the rescue

To help those with async hangs, we recently added async await diagnostic support to LeanSentry.

This allows you to identify the async tasks that are causing the hanging requests , similar to how you would determine the code blocking threads for a regular hang.

If you have async hangs, look for the blocking tasks in the hang diagnostic reports:

LeanSentry identifying async tasks causing the ASP.NET core hang.

You can then follow the task completion “stack trace” similar to a regular stack trace for a blocked function:

LeanSentry identifying the async await chain from where the hanging task was issued.

This async stack effectively shows where in your code the task was issued from, based on the await statement that will be resumed when the task completes.

You can then focus on speeding up/unblocking that specific operation to alleviate the hang.

(Of course, async hangs may also involve synchronously blocked code, e.g. in async task completions, in which case you’ll see regular blocked threads in the diagnostic report.)

To read more about fixing asynchronous hangs with LeanSentry Hang diagnostics, see our new Diagnose async hangs in ASP.NET Core, MVC and WebAPI guide.

task result hangs c#

March 25, 2023 at 6:53 am

task result hangs c#

April 14, 2023 at 4:57 am

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Save my name, email, and website in this browser for the next time I comment.

task result hangs c#

Member-only story

Common async / Task mistakes, and how to avoid them

Stefan Schranz

Stefan Schranz

The .Net async / await mechanism is a godsend when it comes to making asynchronous code accessible, but despite being a superb abstraction, there are still a lot of subtle pitfalls a lot of developers fall into.

Therefore, for this post in my series of async-themed stories I really wanted to bring in some fun (and significant) pitfalls a lot of developers (me included) regularily fall into, because they are often just so subtle to introduce, but so hard to find.

UnobservedTaskExceptions from async Task methods

One of the first things developers learn when working with async code is to avoid async void methods due to their potentially catastrophic impact when throwing exceptions. For async Task methods, the exception is placed on the Task instead (as I explained in https://stefansch.medium.com/what-the-async-keyword-actually-does-bb10d54ce31c ).

So, that’s safe to use, right? The answer is: It mostly is, but depending on the usage it might also not be.

Imagine this code:

When running the code as-is, everything works fine. The exception is thrown properly, since we await DoStuff() , which in turn means we are consuming the Exception placed on the Task .

Now, look at this code instead

It looks very tame, but the problem lies within the missing await . A Task , just like any other reference type, lives on the Heap, and will at some point also be up for Garbage Collection.

When the GC collects a Task , and the Task still has an Exception attached to it, which was never rethrown because it was never awaited, then the CLR will throw an UnobservedTaskException . And believe me, you don’t want to see these in your production log, as debugging them is usually super painful.

We can actually show this behaviour with the following adaptions:

We manually trigger the GC collection, and attach a listener to the event handler which is raised when an UnobservedTaskException occurs.

So, make sure you properly await your Tasks , or properly catch Exceptions inside so they don’t leak outwards!

Properly awaiting concurrent Tasks

A great example to make use of concurrent asynchronous execution is the following. Imagine this code:

This looks fine, but the whole Main() method will take roughly 1 second here, as the execution still happens sequential. We can do better!

Great! We successfully took advantage of concurrency here. We started both units of work at the same time, and the method executed in only 0,5 seconds, despite doing the same amount of work! We await t1 , but by the time t1 is done and we await t2 , t2 is also already done!

However, if you paid attention in the previous section, it’s easy to imagine a problem here. What if DoStuff() throws an Exception in both calls? We would properly await t1 , t1 would raise its Exception , and it would bubble up as we don’t catch the Exception within Main() .

But what about t2 ? We never got to the point where we await t2 ! This will eventually unearth as an UnobservedTaskException again.

Instead, the following should be used:

Task.WhenAll is a utility function of the Task Parallel Library, and essentially bundle a set of awaitables into a single one. That’s all we need to properly fix our example from above. Without modifications, this will only throw the first Exception however, but the other Exceptions are still properly observed.

Async methods run synchronously until the first await

Probably my favourite pitfall of async methods is the behaviour they show with synchronous code at the beginning of the method. See the following example:

Looking at this code, the DoStuff() method waits for 1 second in whole. Since we don’t await it directly but start both Tasks concurrently, one would assume, the total processing takes 1 second, since both methods run independently, right?

Actually, the execution takes 1.5 seconds — How does that happen?

Async methods behave logically similar to non- async methods, at least until the first await , and therefore the first context switch occurs. Up until this point, everything will execute synchronously. So in our case:

  • The first call to DoStuff() starts, and sleeps for 500ms.
  • After the sleep, the Task.Delay(500) starts running, the further execution is deferred, and we return to the Main() method.
  • Now, the second DoStuff() starts, and sleeps for 500ms again.
  • Now, the second delay is also triggered, and we reach the point in the Main() method where we wait for both Tasks to be done. t1 will already be done at this point, as the delay took place at the same time the second Thread.Sleep() ran, so now we essentially wait for the remaining 500ms of the second delay.
  • After 1.5 seconds, everything is done.

With just a minor modification, we can bring the execution time down to 1 second:

Now, the DoStuff() calls will delay and return immediately, while the continuation will take place on a random ThreadPool thread, not blocking the main thread this time.

However, a more common way to solve this is to use Task.Run() to (in our case) start the DoStuff() method, as Task.Run() ensures that the delegate we pass to it is started directly on the Threadpool, also keeping the main thread free.

This is something important to keep in mind, as the structure, as well as the respective CPU or IO nature of the unit of work of async methods can mean precious time in overall execution.

That’s it for now! If this post turns out to be well received, I will continue with another set of common pitfalls soon.

Stefan Schranz

Written by Stefan Schranz

26 year old full stack software developer from Germany - Enthusiatic about C#, .Net and Cloud — Visit me at https://dotschranz.net/

More from Stefan Schranz and ITNEXT

Understanding the Visual Studio Docker-Compose integration

Understanding the Visual Studio Docker-Compose integration

In this post, i’m giving an overview of what happens under the hood when using the visual studio docker-compose integration.

Benchmark results of Kubernetes network plugins (CNI) over 40Gbit/s network [2024]

Alexis Ducastel

Benchmark results of Kubernetes network plugins (CNI) over 40Gbit/s network [2024]

This article is a new run of my previous benchmark (2020, 2019 and 2018), now running kubernetes 1.26 and ubuntu 22.04 with cni version….

Daily bit(e) of C++ | Optimizing code to run 87x faster

Daily bit(e) of C++ | Optimizing code to run 87x faster

Daily bit(e) of c++ #474, optimizing c++ code to run 87x faster for the one billion row challenge (1brc)..

Implementing a custom Trigger for an Isolated .Net Azure Function

Implementing a custom Trigger for an Isolated .Net Azure Function

Adding a custom azure function trigger for the new isolated .net azure function model, step by step, recommended from medium.

A rant about async/await + suggestion to the C# team

Arnon Axelrod

A rant about async/await + suggestion to the C# team

Understanding Concurrency in C# with Threads, Tasks and ThreadPool

Niraj Ranasinghe

Understanding Concurrency in C# with Threads, Tasks and ThreadPool

Concurrency in c# involves the simultaneous execution of tasks within a program, using features like threads and tasks. it’s like having….

task result hangs c#

data science and AI

Understanding Concurrency: Lock, Monitor, Mutex, and Semaphore in C#

Roman Fairushyn

Understanding Concurrency: Lock, Monitor, Mutex, and Semaphore in C#

#csharp-interview #senior #concurrency #lock #monitor #mutex #semaphore.

2 ways to handle exception with c#’s Task.WhenAll

Aman Singh Parihar

2 ways to handle exception with c#’s Task.WhenAll

Exception handling in asynchronous is bit of a tedious job. here, we will look 2 ways to handle it properly..

Advanced NLog features in ASP.NET Core

The Tech Platform

Advanced NLog features in ASP.NET Core

In asp.net core development, logging plays a pivotal role in the lifecycle of an application. among the various logging frameworks….

Solid Understanding of Async/Await and thread in .net

Adarsh Kumar

Solid Understanding of Async/Await and thread in .net

Before comes to async/await comes to understanding of .net runtime(clr). .net code compiles and convert into clr and this version of code….

Text to speech

A Tour of Task, Part 6: Results

The task members discussed in this blog post are concerned with retrieving results from the task. Once the task completes, the consuming code must retrieve the results of the task. Even if the task has no result, it’s important for the consuming code to examine the task for errors so it knows whether the task completed successfully or failed.

The Result member only exists on the Task<T> type; it does not exist on the Task type (which represents a task without a result value).

Like Wait , Result will synchronously block the calling thread until the task completes. This is generally not a good idea for the same reason it wasn’t a good idea for Wait : it’s easy to cause deadlocks .

Furthermore, Result will wrap any task exceptions inside an AggregateException . This usually just complicates the error handling.

Speaking of exceptions, there’s a member specifically just for retrieving the exceptions from a task:

Unlike Result and Wait , Exception will not block until the task completes; if called while the task is still in progress, it will just return null . If the task completes successfully or is cancelled, then Exception will still return null . If the task is faulted, then Exception will return the task’s exceptions wrapped in an AggregateException . Again, this usually just serves to complicate the error handling.

GetAwaiter().GetResult()

The GetAwaiter member was added to Task and Task<T> in .NET 4.5, and it’s available as an extension method on .NET 4.0 using the Microsoft.Bcl.Async NuGet package. Normally, the GetAwaiter method is just used by await , but it is possible to call it yourself:

The code above will synchronously block until the task completes. As such, it is subject to the same old deadlock problems as Wait and Result . However, it will not wrap the task exceptions in an AggregateException .

The code above will retrieve the result value from a Task<T> . The same code pattern can also be applied to Task (without a result value); in this case “GetResult” actually means “check the task for errors”:

In general, I try my best to avoid synchronously blocking on an asynchronous task. However, there are a handful of situations where I do violate that guideline. In those rare conditions, my preferred method is GetAwaiter().GetResult() because it preserves the task exceptions instead of wrapping them in an AggregateException .

Of course, await is not a member of the task type; however, I feel it’s important to remind today’s readers that the best way of retrieving results from a Promise Task is to merely use await . await retrieves task results in the most benign manner possible: await will asynchronously wait (not block); await will return the result (if any) for a successful task; and await will (re-)throw exceptions for a failed task without wrapping them in an AggregateException .

In short, await should be your go-to option for retrieving task results. The vast majority of the time, await should be used instead of Wait , Result , Exception , or GetAwaiter().GetResult() .

  • Constructors
  • AsyncState and CreationOptions
  • Continuations
  • Delegate Tasks
  • Promise Tasks

task result hangs c#

  • Async/await Intro
  • There Is No Thread
  • Don't Block on Async Code
  • React/Redux TodoMVC
  • A Tour of Task
  • Task.Run Etiquette
  • Task.Run vs. BackgroundWorker
  • TCP/IP .NET Sockets FAQ
  • Managed Services
  • IDisposable and Finalizers
  • Option Parsing

James Montemagno

Live, Love, Bike, and Code.

  • Newsletter & Feed

James Montemagno

James Montemagno

Live, Love, Bike, and Code

Copyright © James Montemagno 2024 • All rights reserved. Privacy Policy

Proudly published with Ghost . Branding and design by Cinder Design Co.

  • July 11th, 2017

C# Developers: Stop Calling .Result

I love async/await Task based programming! I talk about it in all my demos, it is in all my libraries, and Frank and I did a whole Merge Conflict podcast episode on it. The problem is that I keep getting bug reports and seeing samples where it is being abused and used completely wrong. I am never a fan of calling a lot of async code in a constructor or in the OnCreate/AppDelegate, but the real issue is when I see stuff like this with .Result:

AHHHHHH!!! We aren't letting StartListeningAsync finish, and we are doing a .Result essentially locking the entire app start code! This makes me the saddest panda in the entire world.

Recently Jon Goldberger wrote a great article on getting started with async/await , but going way back 6 years ago, Stephen Toub from Microsoft 6 wrote an amazing article explaining how to use async/await when dealing with the UI and with event handlers. Both articles are great reads and yes even the 6 year old blog applies to this day.

Stephen's article boils down to this:

On your UI thread, instead of writing:

you can write:

Or instead of writing:

Essentially calling .Result or .Wait will lock up your UI! It is true! So true that I made an entire video right here explaining why you need to stop using .Result!

Copyright © James Montemagno 2017 • All rights reserved. Privacy Policy

task result hangs c#

Dot Net Tutorials

How to Control the Result of a Task in C#

Back to: C#.NET Tutorials For Beginners and Professionals

How to Control the Result of a Task in C# using TaskCompletionSource

In this article, I am going to discuss How to Control the Result of a Task in C# using TaskCompletionSource with Examples. Please read our previous article where we discussed Only One Pattern in C# Asynchronous Programming with Examples.

How to Control the Result of a Task in C#?

So far, we have worked with tasks, and task status depends on an event. For example, if we make an HTTP request or if we make an Async method call, then the status of the task is associated with what happens with the HTTP Request or with the Async Method call, whether it is successful, or there is an exception or the operation is canceled using a cancellation token. With TaskCompletionSource , we can create a task for which we are the ones who will control its status, whether it is successful, canceled, or if it’s thrown an exception.

Constructors, Methods, and Properties of TaskCompletionSource class in C#:

If you go to the definition of TaskCompletionSource class in C#, you will see the following. You can see it is a generic class.

Constructors, Methods, and Properties of TaskCompletionSource class in C#

Constructors of TaskCompletionSource class:

The TaskCompletionSource class in C# provides the following 4 constructors that we can use to create an instance of the TaskCompletionSource class.

  • TaskCompletionSource(): It creates a System.Threading.Tasks.TaskCompletionSource object.
  • TaskCompletionSource(TaskCreationOptions creationOptions): It creates a TaskCompletionSource with the specified options. Here, the parameter creationOptions specify the options to use when creating the underlying Task.
  • TaskCompletionSource(object state): It creates a TaskCompletionSource with the specified state. Here, the parameter state specifies the state to use as the underlying Task’s AsyncState.
  • TaskCompletionSource(object state, TaskCreationOptions creationOptions): It creates a TaskCompletionSource with the specified state and options. Here, the parameter state specifies the state to use as the underlying Task’s AsyncState and the parameter creationOptions specify the options to use when creating the underlying Task.

Property of TaskCompletionSource class in C#:

The TaskCompletionSource class in C# provides the following property.

  • Task<TResult> Task { get; } : It returns the System.Threading.Tasks.Task created by this TaskCompletionSource.

Methods of TaskCompletionSource class in C#:

The TaskCompletionSource class in C# provides the following methods.

  • SetCanceled(): This method is used to set the underlying Task into the Canceled state.
  • SetException(Exception exception): This method is used to set the underlying Task into the Faulted State and binds it to a specified exception. Here, the parameter exception specifies the exception to binding to this Task.
  • SetException(IEnumerable<Exception> exceptions): This method is used to set the underlying Task into the Faulted State and binds a collection of exception objects to it. Here, the parameter exception specifies the collection of exceptions to bind to this Task.
  • SetResult(TResult result): This method is used to set the underlying Task into the RanToCompletion State. Here, the parameter result specifies the result value to bind to this Task.

Example to Understand How to Control the Result of a Task in C#?

Let us understand this with an example. Let’s create a method that will return a task, but it will be a task in which we will control its status. For a better understanding, please have a look at the below image. Here, we have created one method which is returning a Task and taking a string input value. First, we created an instance of the TaskCompletionSource class using one of the overloaded versions of the Constructor. Then we are checking the string value using if-else statements. If the input string value is 1 then we are calling the SetResult method on the TaskCompletionSource instance, this method will set the state of the Task (the task holds by the TaskCompletionSource object) to RanToCompletion. Next, if the string value is 2, then we are calling the SetCanceled method which will set the state of the Task to Canceled. If the value is neither 2 nor 3, then we are calling the SetException method by passing an exception object which will set the state of the Task to Faulted. Finally, we are returning the task by calling the Task property of the TaskCompletionSource class.

Example to Understand How to Control the Result of a Task in C#?

Next, in order to check whether the task is completed, faulted, or canceled, we are going to use the following three properties of the Task class.

  • IsCompleted { get; }: It returns true if the task has been completed; otherwise false.
  • IsCanceled { get; }: It returns true if the task has been completed due to being canceled; otherwise false.
  • IsFaulted { get; }: It returns true if the task has thrown an unhandled exception; otherwise false.

For this, we are creating the following method. From this method, we are calling the EvaluateValue method. The EvaluateValue method returns one task whose status we managed. Remember, if we are passing 2, then we are throwing an exception. Even if we pass 2, then also it will throw a standard task canceled exception. So, to handle those exceptions we are using the try-catch block and also printing the error message on the console window.

Following is the Complete Example Code:

Now, run the application and enter the value as 1. You will get the following output. Is Completed as true and Is canceled and Is faulted as False.

Now, again run the application and enter the value as 2. You will get the following output. Is Completed and Is canceled as True and Is faulted as False. As it is canceled so it will throw a task canceled exception that you can see in the Exception message.

Now, again run the application and enter the value as 3. You will get the following output. Is Completed as True, Is canceled as False and Is Faulted as True. As we throw an exception, so you can that exception message.

So, you can see with TaskCompletionSource, we have complete control over the status of the task.

Example of TaskCompletionSource With Return Value

In the previous example, if you remember we have set null, in the SetResult method. It is also possible to return some value. Let us say we want to return a string value. Then we need to pass the string value to the SetResult method. Apart from this, we need to do two more changes, First, the return type of the method will change from Task to Task<string>, and while creating the instance if the TaskCompletionSource, instead of object we need to pass a string. The following example exactly does the same.

Run the above code and enter the value as 1 and then you will get the following output. You can observe the Result.

In the next article, I am going to discuss Task-based Asynchronous Programming in C# with Examples. Here, in this article, I try to explain How to Control the Result of a Task in C# using TaskCompletionSource with Examples. I hope you enjoy this How to Control the Result of a Task in C# with Examples using TaskCompletionSource article.

About the Author: Pranaya Rout

Pranaya Rout has published more than 3,000 articles in his 11-year career. Pranaya Rout has very good experience with Microsoft Technologies, Including C#, VB, ASP.NET MVC, ASP.NET Web API, EF, EF Core, ADO.NET, LINQ, SQL Server, MYSQL, Oracle, ASP.NET Core, Cloud Computing, Microservices, Design Patterns and still learning new technologies.

3 thoughts on “How to Control the Result of a Task in C#”

Guys, Please give your valuable feedback. And also, give your suggestions about this How to Control the Result of a Task in C# concept. If you have any better examples, you can also put them in the comment section. If you have any key points related to How to Control the Result of a Task in C#, you can also share the same.

Hello, Just a question: do we really need to awit for ttask in this code below ?

try { Console.WriteLine($”Is Completed: {task.IsCompleted}”); Console.WriteLine($”Is IsCanceled: {task.IsCanceled}”); Console.WriteLine($”Is IsFaulted: {task.IsFaulted}”); await task; } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.WriteLine(“EvaluateValue Completed”);

If you are not awaiting the task, then it will not wait till the task is completed. In that case, if any exception occurs, your application will not handle it.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

task result hangs c#

  • Latest Articles
  • Top Articles
  • Posting/Update Guidelines
  • Article Help Forum

task result hangs c#

  • View Unanswered Questions
  • View All Questions
  • View C# questions
  • View C++ questions
  • View Javascript questions
  • View Visual Basic questions
  • View Python questions
  • CodeProject.AI Server
  • All Message Boards...
  • Running a Business
  • Sales / Marketing
  • Collaboration / Beta Testing
  • Work Issues
  • Design and Architecture
  • Artificial Intelligence
  • Internet of Things
  • ATL / WTL / STL
  • Managed C++/CLI
  • Objective-C and Swift
  • System Admin
  • Hosting and Servers
  • Linux Programming
  • .NET (Core and Framework)
  • Visual Basic
  • Web Development
  • Site Bugs / Suggestions
  • Spam and Abuse Watch
  • Competitions
  • The Insider Newsletter
  • The Daily Build Newsletter
  • Newsletter archive
  • CodeProject Stuff
  • Most Valuable Professionals
  • The Lounge  
  • The CodeProject Blog
  • Where I Am: Member Photos
  • The Insider News
  • The Weird & The Wonderful
  • What is 'CodeProject'?
  • General FAQ
  • Ask a Question
  • Bugs and Suggestions

C# Task hanging entire application

task result hangs c#

2 solutions

  • Most Recent

task result hangs c#

Add your solution here

  • Read the question carefully.
  • Understand that English isn't everyone's first language so be lenient of bad spelling and grammar.
  • If a question is poorly phrased then either ask for clarification, ignore it, or edit the question and fix the problem. Insults are not welcome.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Print

IMAGES

  1. How to Control the Result of a Task in C#

    task result hangs c#

  2. How to Control the Result of a Task in C#

    task result hangs c#

  3. C# : Using Task.wait() application hangs and never returns

    task result hangs c#

  4. How to Control the Result of a Task in CSharp

    task result hangs c#

  5. C# : ContinueWith and Result of the task

    task result hangs c#

  6. How to Execute Multiple Tasks in C# with Examples

    task result hangs c#

VIDEO

  1. The .NET Thread Pool Starvation Detection and Improve performance and stability of sync

  2. Task 3 (C#)

  3. task 3 C#

  4. Task 2 (C#)

  5. Taskkill или как завершить множество процессов из CMD

  6. packaged_task ( A Tour of C++: Concurrency and Utilities )

COMMENTS

  1. 'await' works, but calling task.Result hangs/deadlocks

    You are blocking the UI by using Task.Result property. In MSDN Documentation they have clearly mentioned that, "The Result property is a blocking property. If you try to access it before its task is finished, the thread that's currently active is blocked until the task completes and the value is available.

  2. c#

    I have a multi-tier .Net 4.5 application calling a method using C#'s new async and await keywords that just hangs and I can't see why.. At the bottom I have an async method that extents our database utility OurDBConn (basically a wrapper for the underlying DBConnection and DBCommand objects):. public static async Task<T> ExecuteAsync<T>(this OurDBConn dataSource, Func<OurDBConn, T> function ...

  3. Understanding Async, Avoiding Deadlocks in C#

    Task.Wait () does. That would be the end of story but sometimes it cannot be avoided, and it's not the only case. Deadlock might also be cause by other sort of blocking code, waiting for ...

  4. Await, and UI, and deadlocks! Oh my!

    The Task<string>.Result property is strongly typed as a String, and thus it can't return until it has the valid result string to hand back; in other words, it blocks until the result is available. ... One of the very cool things about the new await keyword in C# and Visual Basic is that it's pattern based. It works great with Task and Task ...

  5. Diagnose async hangs in ASP.NET Core, MVC and WebAPI

    Async task type and state filters in the table. For example, you can filter to tasks that are: Started (tasks that have been scheduled for execution) Queued (waiting for a thread to execute, large numbers of tasks in this state signal thread pool exhaustion as the delaying factor). Running: tasks that are executing code synchronously on the CPU.

  6. 'await' works, but calling task.Result hangs/deadlocks in C#

    In C#, using await is the recommended way to get the result of an asynchronous operation. When you use await, the current method is suspended until the awaited task completes, and control is returned to the caller.This allows other threads to continue executing while the asynchronous operation is in progress. On the other hand, calling task.Result on an incomplete task can lead to a deadlock ...

  7. Task<TResult>.Result Property (System.Threading.Tasks)

    If a directory contains no files, it simply calls the FromResult method to create a task whose Task<TResult>.Result property is zero (0). When the tasks finish, the total number of bytes in all a directory's files is available from the Result property. using System.Collections.Generic; using System.IO;

  8. Why does calling an async method from console app hangs forever

    2 answers. Task.WhenAll is waiting for the three tasks to complete, but you haven't even started running them. Use Task.Run to replace new Task, or call Task.RunSynchronously Method to run tasks synchronously on the current TaskScheduler. Task task1 = Task.Run(() => { Console.WriteLine("t1"); Task.Delay(2000); });

  9. Async await hangs in ASP.NET Core, MVC and WebAPI

    If you have async hangs, look for the blocking tasks in the hang diagnostic reports: LeanSentry identifying async tasks causing the ASP.NET core hang. You can then follow the task completion "stack trace" similar to a regular stack trace for a blocked function: LeanSentry identifying the async await chain from where the hanging task was issued.

  10. Common async / Task mistakes, and how to avoid them

    await DoStuff(); } async Task DoStuff() {. await Task.Delay(100); throw new Exception(); } When running the code as-is, everything works fine. The exception is thrown properly, since we await DoStuff (), which in turn means we are consuming the Exception placed on the Task. Now, look at this code instead.

  11. Don't Block on Async Code

    In your "library" async methods, use ConfigureAwait (false) wherever possible. Don't block on Tasks; use async all the way down. Consider the first best practice. The new "library" method looks like this: public static async Task<JObject> GetJsonAsync(Uri uri) { // (real-world code shouldn't use HttpClient in a using block; this is ...

  12. A Tour of Task, Part 6: Results

    T result = task.GetAwaiter().GetResult(); The code above will synchronously block until the task completes. As such, it is subject to the same old deadlock problems as Wait and Result. However, it will not wrap the task exceptions in an AggregateException. The code above will retrieve the result value from a Task<T>.

  13. C# Developers: Stop Calling .Result

    t. Wait (); // BAD ON UI. you can write: Task t = DoWork(); await t; // GOOD ON UI. Essentially calling .Result or .Wait will lock up your UI! It is true! So true that I made an entire video right here explaining why you need to stop using .Result! C# Developers: Stop Calling .Result.

  14. How to Control the Result of a Task in C#

    Next, in order to check whether the task is completed, faulted, or canceled, we are going to use the following three properties of the Task class. IsCompleted { get; }: It returns true if the task has been completed; otherwise false. IsCanceled { get; }: It returns true if the task has been completed due to being canceled; otherwise false.

  15. c#

    Accessing Task.Result is equivalent to: Task<int> task = Execute("..."); task.Wait(); // blocks until done. return 0 < task.Result; If you wanted to further the await chain, you could have Success return a Task<bool> instead. Note that there is a potential for a deadlock depending on the current SynchronizationContext.

  16. [Solved] C# Task hanging entire application

    If you need more info, just ask and ye shall receive. UPDATE : I found out that the code in AddStopwatch_OnClick keeps blocking the thread. C#. { timer.Time = t; await Task.Delay ( 1000 ); } This should be run async, but it's being run on the UI thread, thus blocking the whole UI. Posted8-Aug-13 4:22am. KenBonny.

  17. How to: Return a Value from a Task

    In this article. This example shows how to use the System.Threading.Tasks.Task<TResult> class to return a value from the Result property. To use this example, you must ensure that the C:\Users\Public\Pictures\Sample Pictures directory exists and that it contains files.. Example using System; using System.Linq; using System.Threading.Tasks; class Program { static void Main() { // Return a value ...

  18. Task.Run Method (System.Threading.Tasks)

    The Run (Action, CancellationToken) method is a simpler alternative to the TaskFactory.StartNew (Action, CancellationToken) method. It creates a task with the following default values: Its CreationOptions property value is TaskCreationOptions.DenyChildAttach. It uses the default task scheduler.

  19. c#

    I am new to C# and using Task. I was trying to run this application but my application hangs every time. When I am adding task.wait(), it keeps waiting and never returns. Any help is much appreciated. EDIT: I want to call DownloadString Asynchronously.

  20. Why do Task.Wait and Task.Result even exist? : r/csharp

    Both Task.Wait and Task.Result are blocking and may also cause deadlocks and on top of that they also wrap exceptions in an AggregateException . Now if you are in a situation where you can't use async/await and you have to do sync over async, the preferred way to do it seems to be Task.GetAwaiter().GetResult(); which can still cause deadlocks ...