7

I used to call async methods (fire and forgot?) in constructors by

 Task.Run(async () => await CallAsync());

I heard it's better to use ICommand to execute it.

ICommand MyCmd => new Command(async () => await CallAsync());

public MyClass()
{
     MyCmd.Execute(null);
}

What's the difference between these two methods?

R15
  • 10,727
  • 13
  • 68
  • 139
ca9163d9
  • 24,345
  • 44
  • 175
  • 352
  • 5
    You shouldnt perform any processing in constructors in the first place – FCin Nov 21 '18 at 05:31
  • 1
    `HostingEnvironment.QueueBackgroundWorkItem` is recommended mostly, take a look at here https://blog.stephencleary.com/2014/06/fire-and-forget-on-asp-net.html – Just code Nov 21 '18 at 05:34
  • @FCin, it says initializing the WinForms controls in the constructor can be much faster in this question, https://stackoverflow.com/questions/2521322/what-setup-code-should-go-in-form-constructors-versus-form-load-event. – ca9163d9 Nov 21 '18 at 06:11
  • This refers to updating controls. I'm talking about processing/retrieving data which I assume you do, because you clearly await something. Also, you haven't tagged your question with what framework you are using. WinForms I assume? – FCin Nov 21 '18 at 06:21
  • @FCin, the async method calls methods which read database asynchronously and initialize the controls with the data. – ca9163d9 Nov 21 '18 at 06:25
  • 1
    You've mentioned WinForms and WPF... Could you please clarify what framework you are targeting? Without it looks like dup of https://stackoverflow.com/questions/21354550/async-method-which-is-called-from-constructor (or similar posts) – Alexei Levenkov Nov 21 '18 at 06:39
  • 10
    You're violating the expectation that when a constructor returns, the object is correctly initialized and ready to be used. Consider instead using a *factory* that performs the async works and passes the *results* of that work into an appropriately parameterized constructor for this class instead. That factory method can be `async`. – Damien_The_Unbeliever Nov 21 '18 at 07:08
  • For initializing forms and retrieving data a constructor is the wrong place. you should react on an event being fired – Daniel Schmid Sep 18 '19 at 12:26

1 Answers1

9

Your post makes not much sense.

If you want to fire-and-forget an async method, then just calling it directly is enough.

public Task RunAsync() { }

public Constructor()
{
    RunAsync(); // fire-and-forget by not awaiting and ignoring returned task
}

There is no need to use Task.Run or Command, which technically does nothing on top of running the method.

But this kind of fire-and-forget code is frowned upon, because it makes testing of the code difficult. And starting such code in constructor makes the object creation have unexpected side-effects that are not immediately obvious. It is recommended to have some kind of Initialize method that can be called.

Another issue is that if the method causes an exception, a special handler must be register, otherwise it crashes whole application.

Euphoric
  • 12,302
  • 1
  • 27
  • 41