ASP.NET代码从同步到异步/等待的部分迁移

时间:2017-03-08 13:16:55

标签: c# .net asynchronous

我正在努力在ASP.NET中迁移相当大的代码块,这些代码当前是同步的并将其移动到async / await。我见过的大多数建议都说要一直向下迁移,所以基本上是一个带有所有变化的霰弹枪方法。

为了降低风险,我想限制代码一次更改的范围,但这意味着我需要从同步方法调用异步代码以避免代码重复。

我做了一些搜索,发现了Stephen Cleary的Nito.AsyncEx NuGet包,它有一个AsyncContext.Run方法,可以启用这种类型的异步代码包装。

下面是我如何考虑进行迁移的示例。遗留代码将调用GetContent,它是同步的,现在只是GetContentAsync方法的包装器。这使我可以灵活地从遗留代码中调用同步方法,而这些代码我还没有准备好改变,但同时允许我在任何地方使用异步代码。

我的问题是,这看起来像是一种可行的方法吗?同步包装器方法有任何缺点或潜在的性能问题吗?其他人如何应对将大型代码库迁移到异步的挑战?

using Nito.AsyncEx;
using System.Net.Http;
using System.Threading.Tasks;

namespace AsyncMigration
{
    public class ContentManager
    {
        public string GetContent(string url)
        {
            return AsyncContext.Run(() => GetContentAsync(url));
        }

        public async Task<string> GetContentAsync(string url)
        {
            HttpClient client = new HttpClient();
            return await client.GetStringAsync(url);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

AsyncContext的作用是对所有调用进行排队,并按顺序执行它们。实质上。

您将进一步损害性能,因为AsyncContext需要一个额外的线程来执行您的异步代码,同时阻止当前线程。什么时候叫。您的同步方法将从Web服务器的线程池中获取一个线程。此同步方法将阻止AsyncContext.Run,​​使其线程不可用于处理新调用。反过来,AsyncContext将从线程池中获取另一个线程来完成工作。

换句话说,使用AsyncContext会浪费双倍的线程而不是仅使用纯同步调用。