【问题标题】:How to make an existing code block async in .net?如何在.net中使现有的代码块异步?
【发布时间】:2021-09-13 11:45:06
【问题描述】:

我有一个包含 Linq to SQL 查询和 HTTP 请求的现有代码块,我想将其设为异步以使用更少的线程。

像这样将代码块放在异步方法中就足够了吗?

    public async Task<Customer> ProcessACustomer()
    {
        return await GetCustomer();
    }

    public Task<Customer> GetCustomer()
    {
        // Linq to SQL query here

        // HTTP request here

        Customer customer;
        return Task.FromResult<Customer>(customer);
    }

...或者我是否必须使 GetCustomer() 中的每个逻辑都异步才能完成此操作?

我的障碍是我在该方法中有大量逻辑(上面过于简化),所以时间将是一个问题。此外,我似乎无法将我的 Linq To SQL 查询转换为异步,因为异步扩展方法由于某种原因不可用(System.Data.Linq.Table 不包含 FirstOrDefaultAsync() f.ex. 的定义) .

【问题讨论】:

  • 这能回答你的问题吗? How to call any method asynchronously in c#
  • 如果操作没有作为纯异步 IO 实现,那么您将不会通过将工作卸载到另一个任务来节省任何线程。您想要“使用更少的线程”的理由是什么?您是否需要在操作期间保持用户界面响应?
  • @Crowcoder 不是为了响应能力,而是为了可扩展性:这种方法需要花费大量时间等待,并且会被大量调用。我的理论是,这创建的所有线程都会产生不必要的开销。
  • 好的,那么您将无法通过将某些东西强制到本质上不是异步的异步任务中来获得可伸缩性。如果确实如此关键,您可以将操作推送到另一个服务(队列/无服务器功能等)以转移负担。或者你可以重构不使用像 LINQ to SQL 这样的同步 api。
  • @Fildor 不幸的是,他们相互依赖。

标签: c# .net multithreading async-await


【解决方案1】:

像这样将代码块放在异步方法中就足够了吗?

没有。 GetCustomer 方法不是异步的。它同步执行其工作,然后返回已完成的任务。这不会保存任何线程。

我是否必须使 GetCustomer() 中的每个逻辑都异步才能完成此操作?

如果你想转换成async,那么你应该从另一端开始。不要以使ProcessACustomer(或GetCustomer)异步为目标。相反,从最低级别的 API 开始。无论您的数据库访问方法是什么,首先使 that 异步,然后让 async 从那里长出来。

我的障碍是我在该方法中有大量逻辑(上面过于简化),所以时间将是一个问题。

这是一个经典的权衡。转换为 async 可能值得,或者值得购买更多服务器。

【讨论】:

  • 谢谢斯蒂芬,这正是我需要知道的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多