C#
Asynchronous Programming
Task Parallel Library
Threading
.NET

What's the difference between Foo.Result and Task.Run Foo.Result in C?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

In C#, asynchronous programming comes with several patterns and methods for executing tasks. Two such methods are directly invoking the `.Result` property of a `Task` and using `Task.Run()` followed by accessing `.Result`. While both may seem similar, there are nuanced differences between using `Foo().Result` and `Task.Run(() => Foo()).Result`, which can have significant implications depending on the use case.

Understanding `Foo().Result`

When you have an async method `Foo()`, calling `Foo().Result` runs the method and waits for it to complete by blocking the calling thread until the `Task` is finished. The `.Result` property exposes the outcome of the task upon completion.

Example:

  • Blocking Behavior: It's important to note that `.Result` can lead to thread blocking. If `FooAsync` involves synchronous blocking, it could risk a deadlock, especially on contexts like UI threads.
  • Deadlock Situations: Commonly causes deadlocks in UI threads due to the synchronization context attempting to marshal back to the UI thread, which is blocked waiting for `Result`.
  • Exception Handling: Exceptions thrown in the asynchronous operation are wrapped in an `AggregateException`.
  • ThreadPool Execution: `Task.Run()` dispatches the work to the ThreadPool, potentially bypassing deadlock scenarios often seen with UI threads.
  • Still Blocking: Despite mitigating deadlocks, it still blocks until the task completes, which may not be ideal in responsive applications.
  • More Overhead: There is additional overhead associated with starting new tasks on the ThreadPool.
  • Exception Handling: Similar to `Foo().Result`, exceptions are wrapped in an `AggregateException`.
  • Asynchronous Contexts: For modern applications, it's recommended to use `await` instead of `.Result` to harness true asynchronous behavior, eliminating blocking and enhancing responsiveness.
  • Avoiding Blocking: Consider refactoring synchronous calls in async methods to asynchronous variants wherever possible.
  • UI Applications: Avoid using `.Result` or `.Wait()` within UI event handlers or main UI threads. Instead, refactor to make full use of `async` and `await`.
  • Exception Handling Nuances: Always unwrap `AggregateException` and inspect `InnerExceptions` to handle exceptions appropriately.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.