Hen*_*sen 12 wcf-web-api asp.net-web-api
我们面临着将基于自定义代码的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();
}
}
Run Code Online (Sandbox Code Playgroud)
请不要在代码设计中投入太多价值 - 它只是为了说明问题而构建的,而不是我们在实际解决方案中如何做到这一点.IContactRepository在IoC容器中作为单例注册并注入控制器.Lazy with LazyThreadSafetyMode.ExecutionAndPublication确保只有第一个线程/请求正在运行初始化代码,以下请求将被阻止,直到初始化完成.
Web API是否能够处理等待初始化完成的1000个请求,而其他未命中此Lazy的请求正在服务且IIS没有工作线程耗尽?
Ali*_*tad 10
Task<T>从操作返回将允许代码在后台线程(ThreadPool)上运行并释放IIS线程.所以在这种情况下,我会改变
public IEnumerable<Contact> Get()
Run Code Online (Sandbox Code Playgroud)
至
public Task<IEnumerable<Contact>> Get()
Run Code Online (Sandbox Code Playgroud)
记住要返回一个已启动的任务,否则线程将只是坐着而什么也不做.
懒惰的实现虽然很有用,但与Web API的行为关系不大.所以我不会对此发表评论.无论有没有延迟,基于任务的返回类型都是长时间运行的方式.
| 归档时间: |
|
| 查看次数: |
10388 次 |
| 最近记录: |