【问题标题】:Async library method usage in non-async methods非异步方法中的异步库方法使用
【发布时间】:2017-02-05 22:04:05
【问题描述】:

我创建了一个日志库,日志方法在进入数据库时​​返回一个错误号 (PK),我将其作为用户界面上的错误消息的一部分通知用户。他们在与支持团队交谈时进一步使用该密钥作为参考。

我有一个异步方法来做同样的事情,如下所示:

public class Logger
{
  public async Task<string> LogAsync(Exception ex)
  {
    return await DoLogAsync(ex);
  } 

  // some private method, with multiple optional parameters
  private Task<string> DoLogAsync(Exception ex)
  {
    return Task.Run(() => Log(ex));
  }
}

注意:我承认,这个异步版本只是简单地将同步方法 Log() 包装在 Task.Run 中。我不确定,还应该怎么做!!

现在,我计划在我的所有 API 中使用上述 Log() 方法,如下所示:

public Result<MyObject> Get()
{
  var result = new Result<MyObject>();

  try
  {
    throw new DivideByZeroException();
  }
  catch (DivideByZeroException ex)
  {
    string errorId = await _logger.LogAsync(ex);
    response.AddErrorMessage("Please Contact Admin with this error #"+errorId);
  }

  return result;
}

为了完成上述工作,我需要使 API 方法异步,因为我正在等待记录器调用。

  1. 我应该如何避免更改我的 API 调用异步,只是为了 Logger?使这项工作有哪些其他可能性?
  2. 您认为LogAsync() 真的有用吗?我的 UI 线程无论如何都会等待返回错误号,那么为什么不直接调用同步方法呢?
  3. Log() 方法很少,不需要错误号,作为回报,有点像 log-and-forget。你认为异步版本在这种情况下会有所帮助吗,因为 UI 不会有任何回报?

答案:对于问题 1,这有效:Waiting for async/await inside a task

对于 2 和 3,使用 ADO.Net 实现比 Task.Run 更有意义

【问题讨论】:

  • 这是一个网络应用吗?
  • 那是c#...请在标签中间:)
  • C# 是一门语言。您可以将 C# 用于 ASP.Net 应用程序以及 Web API。
  • 是的!目前是 WebAPI,但我们还有许多其他消费者
  • 所以.. 在这种情况下,您知道 c# 正在您的 服务器 上运行...无论如何.. 请查看此帖子:stackoverflow.com/questions/24777253/…

标签: c# async-await


【解决方案1】:

如果您使用的是 Web API,如果该方法不是 真正 async,我不会选择 async Log 方法。看看斯蒂芬克利里的this 回答。

【讨论】:

  • 哇.. 所以我不需要公开异步方法;而是我会在里面使用 ADO.Net 异步方法。谢谢
  • 如果您在应用程序中使用 ADO.Net 进行数据库访问,那么是的,您应该使用它的 async 方法。这意味着您的 Log 方法仍将是 async ,但您不必将其包装在 Task.Run
  • 感谢您的进一步建议。是的;我能够成功地利用它们
  • 没有。为了使这个答案更准确,它应该说:即使该方法确实是异步的,也不要在 Web 或 Web 服务场景中使用 Task.Run。尤其是当它不是真正的异步时。
  • @johanp 再次阅读我的评论。根据你的回答,不看链接,如果 log 方法真的是异步的,那么使用 task.run 就可以了
【解决方案2】:

如果您开始在代码中使用async-await 方法 - 请注意async 将遍布您应用程序的整个管道。

所以

我应该如何避免更改我的 API 调用异步,只是为了 记录器?使这项工作有哪些其他可能性?

回答:不要使用async

您认为 LogAsync() 真的有用吗?我的 UI 线程将 无论如何都在等待返回错误号,所以为什么不 只需调用同步方法?

回答:好处是在等待期间,UI 将是“响应式”的 - 例如,用户将能够在另一个屏幕上移动应用程序的窗口或将其最小化。

Log() 方法很少,不需要错误号,在 回报,一种记录和忘记。你认为异步版本会是 在这种情况下很有帮助,因为 UI 不会期待任何返回?

答案:同上一个答案

【讨论】:

  • 谢谢;所以,我不想让 API 异步,而是像有人在另一篇文章中建议的那样使用如下:var t = Task.Run( async () =&gt; { await lIB.LogAsync(); }); 你认为这种方法有什么副作用吗?
  • 副作用:您通过保留/创建另一个线程只是为了什么都不做而浪费资源。在 IO 操作(数据库查询是哪个)中,线程会发送请求并等待响应。
  • 谢谢;看来,在这种情况下我最好不使用异步
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-06
  • 2019-12-02
  • 1970-01-01
  • 2016-10-13
  • 1970-01-01
相关资源
最近更新 更多