8

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?

8
  • 6
    You shouldnt perform any processing in constructors in the first place Commented Nov 21, 2018 at 5:31
  • 1
    HostingEnvironment.QueueBackgroundWorkItem is recommended mostly, take a look at here blog.stephencleary.com/2014/06/fire-and-forget-on-asp-net.html Commented Nov 21, 2018 at 5:34
  • 1
    You've mentioned WinForms and WPF... Could you please clarify what framework you are targeting? Without it looks like dup of stackoverflow.com/questions/21354550/… (or similar posts) Commented Nov 21, 2018 at 6:39
  • 13
    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. Commented Nov 21, 2018 at 7:08
  • 1
    For initializing forms and retrieving data a constructor is the wrong place. you should react on an event being fired Commented Sep 18, 2019 at 12:26

2 Answers 2

8

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.

Sign up to request clarification or add additional context in comments.

2 Comments

This does not look right. The code you show never runs the returned task! That's why Task.Run is used in the question's first code snippet.
@ToolmakerSteve How are you testing it? One issue might be that application quits before the task finishes running. The running task will not prevent the application from quitting. So you must make sure the application runs long enough to let the task finish.
-3

Task.Run(async () => await CallAsync()) can be simplified to Task.Run(CallAsync) without loss of any functionality.

A difference can relate to implementation of your Command class, but it's not shown in your question. There is no difference in the shown fragment. You can implement the Execute method to create a special set of commands.

The comment to the previous answer: 'There is no need to use Task.Run or Command, which technically does nothing on top of running the method' - this statement is not correct. 'Task.Run' creates a new thread while direct method calling doesn't.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.