【问题标题】:How to synchronously call async method from quartz schedule job如何从石英调度作业同步调用异步方法
【发布时间】:2016-07-14 15:29:28
【问题描述】:

我正在尝试从我的 quartz.net 计划作业中调用 webapi 方法。我不确定我的做法是否正确?如果这是正确的方法或有更好的方法可用,任何人都可以提供帮助吗?

MethodRepository.cs

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

石英作业:

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

通用 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>>();
}

但石英文档说我不能在石英作业中使用异步方法。那如何才能使用 Web API 方法呢?

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

public void Execute(IJobExecutionContext context)
{
    var result = _repo.GetResult().Result;
}

【问题讨论】:

标签: c# quartz-scheduler quartz.net


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

    另外,他们似乎正在处理AsyncJob

    【讨论】:

    • 在你真正需要它之前捕获所有异常并不是一个好主意(并且可以处理像OutOfMemoryException这样的东西)。更糟糕的是过滤并重新抛出其中一些或一些嵌套的。您可以使用 task.GetAwaiter().GetResult() 方法轻松避免这种情况,这可以帮助您摆脱 AggregateException 并处理原始异常。
    • 当然。只需调用 Task.Result 就会引发 AggregateException - 仅此而已。
    • @lorond,根据Quartz Best Practices,您实际上应该处理工作中的所有异常,所以我认为它算作“真正需要它”。
    猜你喜欢
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    相关资源
    最近更新 更多