Comments (7)
The option I brought up was about moving the constructor async logic to a class method upon invocation.
I’m struggling to understand why this logic must be in the constructor. When you say UI, which technology are you referring to? Razor View? WPF/UWP Xaml?
from aspnetcorediagnosticscenarios.
@mihirdilip Generally speaking, you should avoid sync over async
wherever possible.
The section Avoid using Task.Result
and Task.Wait
has more details, why you should avoid it. (thread-pool starvation, deadlocks, ...)
If you really have to do some sync over async
, there are many different examples with explanations in the Deadlocks-section.
As an example, that could be a small Utility class for your needs, still not recommended to use sync over async:
public static class AsyncUtility
{
/// <summary>
/// Executes an async operation synchronously without risking a deadlock.
/// </summary>
/// <typeparam name="T">The result type of the operation.</typeparam>
/// <param name="asyncOperation">The async operation.</param>
/// <returns>The operation result.</returns>
public static T ExecuteSynchronously<T>(Func<Task<T>> asyncOperation)
{
return Task.Run(asyncOperation).Result;
}
/// <summary>
/// Executes an async operation synchronously without risking a deadlock.
/// </summary>
/// <param name="asyncOperation">The async operation.</param>
public static void ExecuteSynchronously(Func<Task> asyncOperation)
{
Task.Run(asyncOperation).Wait();
}
}
from aspnetcorediagnosticscenarios.
One option is to delay initialization until method invocation occurs. Basically:
public async Task FooAsync()
{
await EnsureInitializedAsync();
//do actual operation
}
The RedisCache class is a good example of this pattern. It does not connect to Redis until the first interaction with the server:
https://github.com/dotnet/extensions/blob/master/src/Caching/StackExchangeRedis/src/RedisCache.cs#L272
from aspnetcorediagnosticscenarios.
If there's no way to avoid it then you're in the bad situation described in the document. There's no workaround for needing to block using Task.Wait or Task.Result, nor is there a good way to do it.
from aspnetcorediagnosticscenarios.
Thanks for your reply @epignosisx,
Your suggestion does help with ensuring if the initialization initiated by Fire and Forget in Constructor is completed before utilizing it. Which certainly helps with Fire and Forget initialization.
What if I need to call Async method and the value retured is used by next statement in within Contructor? UI is depended on this so has to happen within Constructor.
May be not the best example..
public interface IFoo { }
public class Foo : IFoo
{
// Instance will be created from Container (IServiceProvider)
// and so cannot use static factory pattern
public Foo(IService service)
{
// Only have Async method on the API
// Is this the best right way or there is a better way of achieving the same?
var a = service.BarAsync().GetAwaiter().GetResult();
DoSomethingWith(a); // Now part of UI may be depended on value a
DoSomethingElseWith(a); // And another part of UI may be depended on value a
}
}
from aspnetcorediagnosticscenarios.
@epignosisx, may be it is just a bad example or may be I need to rephrase it.
It is not a problem I am currenly having but, in case if I do come across this problem what do I do. UI could be WPF/UWP/Xamarin.Forms Xaml.
To rephrase my query, if you forget about this Async call in Constructor for now.
What is the best practice to call Async method synchronously because I do not have any synchronous method on am API I may be using? It could be within constructor or a method or (in worst case) a property.
What shall I use or what is the safest to use on WPF/UWP/Xamarin.Forms and ASP.NET Core?
public interface IFoo { }
public class Foo : IFoo
{
public Foo(IService service)
{
var a = service.BarAsync().GetAwaiter().GetResult();
}
public void Bar()
{
var a = service.BarAsync().GetAwaiter().GetResult();
}
}
public void Bar()
{
// Task may return result or not depending on the requirement so this can be ignored.
// Is this the best (right?) way or there is a better way of achieving the same?
service.BarAsync().GetAwaiter().GetResult();
// The same can be achieved in many different ways.
service.BarAsync().RunSynchronously();
service.BarAsync().Wait();
service.BarAsync().Result;
}
from aspnetcorediagnosticscenarios.
@epignosisx and @kapsiR
Thank you very much for your help and guidance. Much appreciated..
from aspnetcorediagnosticscenarios.
Related Issues (20)
- IHttpClientFactory Question HOT 2
- Do You Have This Rules as Sonarqube Rules HOT 1
- Feature: Adding contributors section to the README.md file. HOT 2
- Copy Paste error in AsyncGuidance.md HOT 1
- Question about example HOT 2
- Make TaskCreationOptions.LongRunning advice more explicit HOT 6
- await Task.WhenAll(task1, task2); task1.Result; task2.Result HOT 10
- Analyzer for “Prefer async/await over directly returning Task”? HOT 2
- "Always create `TaskCompletionSource<T>` with `TaskCreationOptions.RunContinuationsAsynchronously`" may be detrimentally overcorrecting. HOT 1
- Typo in HttpClientGuidance.md HOT 2
- How about long running work that is done using an async method HOT 5
- Mapping CancellationToken in controller's actions HOT 1
- Use `async/await` in 'A note about WebClient' section
- CPU consumption while using Task.Run vs Background thread HOT 2
- WindowsIdentity.RunImpersonated errors HOT 1
- Possible clarification for long-running work advice HOT 1
- Async void is not always bad HOT 11
- Event handler (async void) with EventArgs processing
- ASP.NET Core does have a SynchronizationContext when using Blazor HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from aspnetcorediagnosticscenarios.