我有一个将一些数据插入数据库的操作方法。我试图让它异步。代码如下所示:
public async Task<ActionResult> Create([DataSourceRequest] DataSourceRequest request, MyClass model)
{
return await Task.Run(() =>
{
if (model != null && ModelState.IsValid)
{
try
{
repository.Insert(model);
anotherSyncCall(model);
}
catch { ModelState.AddModelError("", "Error"); }
}
return Json(new[] { model }.ToDataSourceResult(request, ModelState));
});
}
Repository的insert方法是同步的,我是否必须使它异步才能使这个action方法异步?
存储库插入代码:
private EFDbContext context;
public Repository()
{
context = new EFDbContext(Authentication.GetConnectionClaim);
}
//......
public void Insert(T entity)
{
context.Set<T>().Add(entity);
context.SaveChanges();
}
这是在重复请求下的时间图。
正如您所看到的,他们正在同步工作。我确信我的客户端Ajax调用是异步的,因为所有请求都是立即生成的,并且他们会随着时间的推移收到响应。
更新
这是我用以下代码测试我的应用的代码:
for (var i = 0; i < 100; i++) {
$.ajax({
method: 'post',
url: 'http://192.168.1.8/xx/xx/Read',
data: 'sort=&page=1&pageSize=10&group=&filter='
});
}
我已经尝试将SessionState
设置为Readonly
,因为@Dan建议但是id并没有改变时间。
关于第二个想法,也许它导致了这个问题的剑道UI的ToDataSourceResult
扩展方法?但无论如何,我为此Task
制作了不同的action method
。
答案 0 :(得分:2)
您是否尝试过将SessionState设置为ReadOnly?这可以在控制器上完成:
[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
根据微软的说法:
对每个会话的访问ASP.NET会话状态是独占的,这意味着如果两个不同的用户发出并发请求,则同时授予对每个单独会话的访问权限。但是,如果对同一会话发出两个并发请求(通过使用相同的SessionID值),则第一个请求将获得对会话信息的独占访问权。第二个请求仅在第一个请求完成后执行。 (如果由于第一个请求超过锁定超时而释放信息的独占锁定,则第二个会话也可以访问。)如果@ Page指令中的EnableSessionState值设置为ReadOnly,则只读请求会话信息不会导致会话数据的独占锁定。但是,会话数据的只读请求可能仍然需要等待会话数据的读写请求设置的锁定才能清除。
答案 1 :(得分:1)
本质上在同步方法中使用Task.Run并不意味着您的代码执行速度更快。您最终会阻止您的服务器响应(如图片所示)。服务器无法同时处理所有这些请求,这就是您获得上述行为的原因。如果您的意图是客户端的非阻塞行为。您应该从客户端使用ajax调用此同步方法,以便用户不会冻结。如果你想深入到服务器端的async / await主要用于用户数量有限的应用程序,我建议你这个幻灯片Stephen Cleary Conference以及阅读他的博客。