8

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;
}
walen
  • 7,103
  • 2
  • 37
  • 58
Mukil Deepthi
  • 6,072
  • 13
  • 71
  • 156
  • Possible duplicate of [How to call asynchronous method from synchronous method in C#?](http://stackoverflow.com/questions/9343594/how-to-call-asynchronous-method-from-synchronous-method-in-c) – lorond Jul 14 '16 at 21:25

2 Answers2

21

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();
}
Marko Lahma
  • 6,586
  • 25
  • 29
4

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.

William Xifaras
  • 5,212
  • 2
  • 19
  • 21
  • 2
    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. – lorond Jul 14 '16 at 21:34
  • 1
    Sure. Just calling out that Task.Result raises AggregateException - nothing more. – William Xifaras Jul 14 '16 at 21:39
  • @lorond, according to [Quartz Best Practices](https://www.quartz-scheduler.net/documentation/best-practices.html) you actually _should_ handle all exceptions inside the job, so I think it counts as "really need it". – alpha-mouse Jun 15 '19 at 19:46