如何从石英计划作业同步调用异步方法

Muk*_*thi 6 c# quartz-scheduler quartz.net

我试图从我的quartz.net计划工作中调用webapi方法.我不确定我的做法是否正确?如果这是正确的方法或者有更好的方法可以帮助任何人吗?

MethodRepository.cs

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

石英工作:

public async void Execute(IJobExecutionContext context)
{
    var results= await _repo.GetResult();
}
Run Code Online (Sandbox Code Playgroud)

通用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>>();
}
Run Code Online (Sandbox Code Playgroud)

但石英文档说我不能在石英作业中使用异步方法.那么Web API方法怎么样呢?

我可以将quartz作业执行方法更改为:

public void Execute(IJobExecutionContext context)
{
    var result = _repo.GetResult().Result;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*hma 12

Quartz.NET 3.0支持async/await开箱即用.因此,您现在可以(并且必须)将Execute方法声明为Task返回,并且您可以使用async/await.

public async Task Execute(IJobExecutionContext context)
{
    var result = await _repo.GetResult();
}
Run Code Online (Sandbox Code Playgroud)


Wil*_*ras 4

如果您必须这样做 - 那么是的,您可以这样做,但它会阻塞调用线程,直到异步操作完成。

Task.Result会将任何异常包装到 AggregateException 中。

所以你应该把你的 httpclient 调用放在 try catch 中。

  try
  {
      var result = _repo.GetResult().Result;
  }
  catch (AggregateException ae)
  {
      // handle exception
  }
Run Code Online (Sandbox Code Playgroud)

另外,他们似乎正在开发AsyncJob

  • 在您真正需要之前捕获所有异常并不是一个好主意(并且可以处理类似“OutOfMemoryException”之类的异常)。更糟糕的是过滤并重新抛出其中一些或一些嵌套的。您可以使用“task.GetAwaiter().GetResult()”方法轻松避免这种情况,它可以帮助您摆脱“AggregateException”并处理原始异常。 (2认同)