gpt4 book ai didi

asp.net-web-api - Web API 并发性和可扩展性

转载 作者:行者123 更新时间:2023-12-04 01:04:26 28 4
gpt4 key购买 nike

我们面临着将基于自定义代码的 REST 服务转换为 Web API 的任务。该服务有大量请求并对可能需要一些时间才能加载的数据进行操作,但一旦加载,它就可以被缓存并用于为所有传入请求提供服务。该服务的先前版本将有一个线程负责加载数据并将其放入缓存中。为了防止 IIS 用尽工作线程,客户端将获得“稍后再回来”响应,直到缓存准备好。

我对 Web API 的理解是,它通过对任务进行操作来内置异步行为,因此请求的数量与所持有的物理线程的数量没有直接关系。

在服务的新实现中,我计划让请求等到缓存准备好,然后做出有效回复。我做了一个非常粗略的代码草图来说明:

public class ContactsController : ApiController
{
private readonly IContactRepository _contactRepository;

public ContactsController(IContactRepository contactRepository)
{
if (contactRepository == null)
throw new ArgumentNullException("contactRepository");
_contactRepository = contactRepository;
}

public IEnumerable<Contact> Get()
{
return _contactRepository.Get();
}
}

public class ContactRepository : IContactRepository
{
private readonly Lazy<IEnumerable<Contact>> _contactsLazy;

public ContactRepository()
{
_contactsLazy = new Lazy<IEnumerable<Contact>>(LoadFromDatabase,
LazyThreadSafetyMode.ExecutionAndPublication);
}

public IEnumerable<Contact> Get()
{
return _contactsLazy.Value;
}

private IEnumerable<Contact> LoadFromDatabase()
{
// This method could be take a long time to execute.
throw new NotImplementedException();
}
}

请不要在代码设计中投入太多值(value)——它只是为了说明问题而构建的,并不是我们在实际解决方案中是如何做到的。 IContactRepository 在 IoC 容器中注册为单例,并注入(inject)到 Controller 中。 Lazy 与 LazyThreadSafetyMode.ExecutionAndPublication 确保只有第一个线程/请求正在运行初始化代码,随后的 rquest 被阻塞,直到初始化完成。

Web API 是否能够处理等待初始化完成的 1000 个请求,而其他未命中此 Lazy 的请求正在被服务并且 IIS 不会耗尽工作线程?

最佳答案

返回 Task<T>从 Action 中将允许代码在后台线程(ThreadPool)上运行并释放IIS 线程。所以在这种情况下,我会改变

public IEnumerable<Contact> Get()


public Task<IEnumerable<Contact>> Get()

记得返回 开始 任务,否则线程将只是坐着什么也不做。

惰性实现虽然很有用,但与 Web API 的行为几乎没有关系。所以我不会对此发表评论。不管有没有惰性,基于任务的返回类型都是长期运行的方法。

我有两篇可能对你有用的博文: herehere .

关于asp.net-web-api - Web API 并发性和可扩展性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10173933/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com