How to synchronously call async method from quartz schedule job

11,562

Solution 1

If you have to do it - then yes you can do that, but it will block the calling thread until the asynchronous operation is complete.

Task.Result will wrap any exception into an AggregateException.

So you should probably put your httpclient call in a try catch.

  try
  {
      var result = _repo.GetResult().Result;
  }
  catch (AggregateException ae)
  {
      // handle exception
  }

Also, it seems they are working on an AsyncJob.

Solution 2

Quartz.NET 3.0 supports async/await out of the box. So you can (and must) now declare Execute method as Task returning and you can use async/await.

public async Task Execute(IJobExecutionContext context)
{
    var result = await _repo.GetResult();
}
Share:
11,562
Mukil Deepthi
Author by

Mukil Deepthi

Updated on July 02, 2022

Comments

  • Mukil Deepthi
    Mukil Deepthi almost 2 years

    I am trying to call a webapi method from my quartz.net schedule job. I am not sure whether the way I am doing is right? Can anyone help if this is the right way or is there any better approach available?

    MethodRepository.cs

    public async Task<IEnumerable<ResultClass>> GetResult(string queryCriteria)
    {
        return await _httpClient.Get(queryCriteria);
    }
    

    Quartz job:

    public async void Execute(IJobExecutionContext context)
    {
        var results= await _repo.GetResult();
    }
    

    generic Httpclient :

    public async Task<IEnumerable<T>> Get(string queryCriteria)
    {
        _addressSuffix = _addressSuffix + queryCriteria;
        var responseMessage = await _httpClient.GetAsync(_addressSuffix);
        responseMessage.EnsureSuccessStatusCode();
        return await responseMessage.Content.ReadAsAsync<IEnumerable<T>>();
    }
    

    But the quartz documentation says I can't use async method in a quartz job. How can one the Web API method then?

    Can I change the quartz job execute method as:

    public void Execute(IJobExecutionContext context)
    {
        var result = _repo.GetResult().Result;
    }
    
  • lorond
    lorond almost 8 years
    It is not a good idea to catch all exceptions until you really need it (and can handle something like OutOfMemoryException). Even worse is to filter and re-throw some of them or some of nested ones. You can easly avoid this with task.GetAwaiter().GetResult() method, that could help you to get rid of AggregateException and work with original exceptions.
  • William Xifaras
    William Xifaras almost 8 years
    Sure. Just calling out that Task.Result raises AggregateException - nothing more.
  • alpha-mouse
    alpha-mouse almost 5 years
    @lorond, according to Quartz Best Practices you actually should handle all exceptions inside the job, so I think it counts as "really need it".