2

I'm converting previous synchronous Quartz.NET 2.0 jobs to the new async Quartz.NET 3.0 framework and I was curious what the best practice was for dealing with the results of calling another async method that you need the results from?

In my scenario I'm using a package called CliWrap that is for interacting with command line executables. In my scenario I use their buffered option which captures the stdout and stderr streams into a buffer that you can then inspect.

My question then, is it better to have the Quartz job wait on the result from the CliWrap call (Option 1 below) or is it better to have the job be async as well and assign a JobListener to grab the buffered result when the job completes (Option 2 below)? Thanks

Option 1

public Task Execute(IJobExecutionContext context) {
    MyJobDetails jobDetails = context.MergedJobDataMap["MyJobDetails"] as MyJobDetails;
    var result = Cli.Wrap(jobDetails.ExecPath))
        .WithArguments(jobDetails.Arguments)
        .ExecuteBufferedAsync();
    var r= result.GetAwaiter().GetResult();
    //do whatever with output
    string stdout = r.StandardOutput;  
    return result;
}

Option 2

public async Task Execute(IJobExecutionContext context) {
    MyJobDetails jobDetails = context.MergedJobDataMap["MyJobDetails"] as MyJobDetails;
    var result = await Cli.Wrap(jobDetails.ExecPath))
        .WithArguments(jobDetails.Arguments)
        .ExecuteBufferedAsync();
    //set the result in the context
    context.Result = result;
}


public class SimpleListener : IJobListener {
    public Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default(CancellationToken)) {
        var result = (BufferedCommandResult)context.Result;
        //do whatever with output
        string stdout = result.StandardOutput;            
    }        
}
snappymcsnap
  • 2,050
  • 2
  • 29
  • 53

1 Answers1

2

You should almost never use GetAwaiter().GetResult() in any context. You are blocking the thread with GetAwaiter().GetResult() and it will waste the whole purpose of async and await.

You should go with Option 2.

Kahbazi
  • 14,331
  • 3
  • 45
  • 76
  • Yeah I guess that's the way to look at it. It's just weird because their documentation has that Execute method defined with or without async which I don't understand? Because if I use await then it will just continue to run asynchornously and then return control to that block when it completes right? – snappymcsnap May 01 '20 at 14:38