我是这样写的..
public async Task<string> SaveAsync(string modelStr) { var codeModel = JsonConvert.DeserializeObject<Model.GUT_CODE>(modelStr); await FillModelAsync(codeModel, false); codeModel.SerialModifiedTime = DateTime.Now; var result = await _bllCode.UpdateAsync(codeModel); //更新缓存, 不需要等待 new CodeCacheManager(_bllCode).UpdateWholeCodeCacheItemAsync(codeModel); return result.ToString(); }
private async Task FillModelAsync<T>(T model, bool isAdd) where T : BaseModel, new() { Action<T, bool> fillModel = (m, a) => CommonTool.FillModel(m, a); await Task.Factory.FromAsync(fillModel.BeginInvoke, fillModel.EndInvoke, model, isAdd, null); }
debug发现进CommonTool.FillModel方法新开了一个线程, 原来的线程丢弃了, 更加奇怪的是访问FillModel中访问数据库后用的是同一个新线程.
我想实现的是: 同一个线程一直用到访问数据库, 然后丢弃线程等待IO, IO完成后通知Asp.Net用新线程继续处理, 全程代码应该是可以访问到HttpContext的.
那么如何不新开线程呢? 求大家指点.
貌似自己写的实现无法像微软的实现一样单线程, 不借助APM接口的话?
通过方法参数传递HttpContext
有没有办法异步而不开新线程的吗
@xiezhenhao: 异步会造成线程切换,如果不想进行线程切换,就不要用异步。
@dudu: 其实我关心的不是HttpContext没有传递, 而是调用异步方法时的效率和正确线程顺序.
看了这篇文章FromAsync(asyncResult, …) vs FromAsync(beginMethod, …), 以及MSDN上的解释,
The FromAsync overloads that take an asyncResult parameter are not as efficient as the overloads that take a beginMethod parameter. If performance is an issue, use the overloads that provide the beginMethod/endMethod pattern.
The beginMethod delegate is started on the thread that FromAsync is running on. This method throws any exceptions thrown by the beginMethod.
似乎使用FromAsync(beginMethod, …)能解决我的问题.
task里面执行的方法和线程一样不能直接使用httpcontext,因为获取出来的就是null,这两种都需要通过参数传递当前线程的httpcontext进去,线程执行的方法才能获取到,也就是您这里必须通过model来传递一个httpcontext