我正在努力在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);
}
}
}
答案 0 :(得分:0)
AsyncContext的作用是对所有调用进行排队,并按顺序执行它们。实质上。
您将进一步损害性能,因为AsyncContext需要一个额外的线程来执行您的异步代码,同时阻止当前线程。什么时候叫。您的同步方法将从Web服务器的线程池中获取一个线程。此同步方法将阻止AsyncContext.Run,使其线程不可用于处理新调用。反过来,AsyncContext将从线程池中获取另一个线程来完成工作。
换句话说,使用AsyncContext会浪费双倍的线程而不是仅使用纯同步调用。