Call Asynchronous Method in Constructor

Call asynchronous method in constructor?

The best solution is to acknowledge the asynchronous nature of the download and design for it.

In other words, decide what your application should look like while the data is downloading. Have the page constructor set up that view, and start the download. When the download completes update the page to display the data.

I have a blog post on asynchronous constructors that you may find useful. Also, some MSDN articles; one on asynchronous data-binding (if you're using MVVM) and another on asynchronous best practices (i.e., you should avoid async void).

Can we call an async method from a constructor?

You cannot have async constructors.

One alternative is to have async factory methods:

public class MyModel
{
public SFOpportunity Opportunity { get; set; }
private MyModel() { }

public static async Task<MyModel> CreateAsync(string id)
{
var result = new MyModel();
await result.setOpportunityAsync(id);
return result;
}

private async Task setOpportunityAsync(string id)
{
...
}
}

Optimising an asynchronous call in a constructor using JoinableTaskFactory.Run

Below is the best set of conclusions that I could derive from all the comments on the question.

Point #1: Injection Constructors should be simple

Injection constructors should be simple, and in the context of Fluent Validation, the MustAsync method should help to simplify asynchronous validation.

Point #2: Warning not applicable to .NET Core

While I can use JoinableTaskFactory, I should not be getting this warning, because the problem it is trying to solve is not applicable to .NET Core.

Below is the description from the documentation for JoinableTaskFactory. It applies to situations where joining threads to the main thread could cause deadlocks.

A factory for starting asynchronous tasks that can mitigate deadlocks when the tasks require the Main thread of an application and the Main thread may itself be blocking on the completion of a task.

Thus, one can safely ignore the warning in the cases where it is simply not possible to rewrite the code. (Note the use of Task.Run(), which is the recommended way to launch a compute-bound task as of .NET Framework 4.5.)

#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
Task.Run(() => MethodAsync()).Wait();
#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits

Point #3: How to implement JoinableTaskFactory

If you want to use JoinableTaskFactory anyway, this is taken from comments on another related answer.

For .NET Framework projects, use ThreadHelper.JoinableTaskFactory.

For .NET Core projects, if you want to use JoinableTaskFactory, do not create a new context every time you use it. You should create one shared JoinableTaskContext object and use that one object throughout the application (per request or per process). This is the case when SynchronizationContext.Current == null.

Point #4: Visual Studio Warnings

The warning comes from the NuGet package Microsoft.VisualStudio.Threading.Analyzers. It is useful to keep it installed, because it will also warn you when you use code like MethodAsync().Result or MethodAsync().Wait() when you should instead be using await MethodAsync().

How can I call async method from constructor?

Don't do this in the constructor but in the loaded event of the window instead.
You can mark the loaded eventhandler as async.

c# calling async function from constructor gives green underline in VS

Indeed, C# / .NET does not currently support async constructors, so you'd have to use either an async static factory method, or an async initialize method after the constructor has finished; however - this line is not true:

that is just a workaround to get rid of the green underline.

This is not just a workaround; if you haven't awaited an async method, then you don't know when it has finished, so you can't rely on the state that it is meant to initialize - and you have have inadvertent thread-safety issues (as you now effectively have two active executions, which is comparable to two active threads). As such, refactoring (in one of the ways cited above) is necessary for correctness.

Can constructors be async?

Constructor acts very similarly to a method returning the constructed type. And async method can't return just any type, it has to be either “fire and forget” void, or Task.

If the constructor of type T actually returned Task<T>, that would be very confusing, I think.

If the async constructor behaved the same way as an async void method, that kind of breaks what constructor is meant to be. After constructor returns, you should get a fully initialized object. Not an object that will be actually properly initialized at some undefined point in the future. That is, if you're lucky and the async initialization doesn't fail.

All this is just a guess. But it seems to me that having the possibility of an async constructor brings more trouble than it's worth.

If you actually want the “fire and forget” semantics of async void methods (which should be avoided, if possible), you can easily encapsulate all the code in an async void method and call that from your constructor, as you mentioned in the question.

Call asynchronous function inside constructor

You can't do this inside the constructor of your StatefulWidget

You need to make your call inside the the initState() method of the PositionWidgetState (the State of your PositionWidget

class PositionWidgetState extends State<PositionWidget> {
var res;

@override
void initState() {
res = getNotification(widget.streetName);
}

You'll probably need to a FutureBuilder or StreamBuilder to deal with the result



Related Topics



Leave a reply



Submit