0

Here is one class with 1 method,

public class ApiService
{
    public async Task StartAsync()
    {
        await _webHost.StartAsync();
    }
}

Now trying to call above class/method like below,

public static async Task Main(string[] args)
    {

        HostFactory.Run(
        configuration =>
        {
            configuration.Service<ApiService>(
                service =>
                {
                    service.ConstructUsing(x => new ApiService());
                    service.WhenStarted(x => x.StartAsync());
                });

            configuration.RunAsLocalSystem();
        });
    }

If I'm putting await like this, it's giving error, where to put async/await here?

service.WhenStarted(x => await x.StartAsync());
user584018
  • 10,186
  • 15
  • 74
  • 160
  • Try to put `await` keyword outside lambda expression: `await HostFactory.Run(configuration => { configuration.Service(service => { service.WhenStarted(x => x.StartAsync()); }); ... });`. – Tetsuya Yamamoto Jan 23 '19 at 05:02
  • Yes, getting error - 'TopshelfExitCode' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'TopshelfExitCode' could be found (are you missing a using directive or an assembly reference?) – user584018 Jan 23 '19 at 05:06
  • I'm trying to call in `Topshelf` configuration – user584018 Jan 23 '19 at 05:06
  • 1
    Seems like you can't. You will have to run it synchronously. https://stackoverflow.com/questions/39656932/how-to-handle-async-start-errors-in-topshelf also https://github.com/Topshelf/Topshelf/issues/375 – JohanP Jan 23 '19 at 05:07

1 Answers1

2

I don't know the signature for WhenStarted() and since I can't find in in the documentation this may or may not work. Generally if you need to await a call you also have to mark the call as async.

service.WhenStarted(async (x) => await x.StartAsync());
Erik Philips
  • 53,428
  • 11
  • 128
  • 150
  • 1
    Why not `service.WhenStarted(x => x.StartAsync());` – Cheng Chen Jan 23 '19 at 05:23
  • `T` is not equal to `TaskT` or `void` is not equal to `Task`. – Erik Philips Jan 23 '19 at 07:45
  • I think `async (x) => await x.StartAsync()` just adds an extra wrapper for `x => x.StartAsync()`, they should both work. – Cheng Chen Jan 23 '19 at 07:55
  • 1
    It's pretty easy to test. A method *must* return a task to use await. If you don't call await on a async task, it returns a `Task` or `Task` (hopefully not void). [It can be easily tested](https://dotnetfiddle.net/9WqT9w). I highly recommend reading Stephen Cleary's blog on async. It doesn't add anything, the async source is propagated up the call stack. This also can be tested, if each method was wrapped the results from any method would not be literally equal, but [they are](https://dotnetfiddle.net/OlF6lt). – Erik Philips Jan 23 '19 at 08:42