MSt*_*odd 1 .net c# asp.net-mvc task-parallel-library async-await
我有一个控制器操作,它获取文档类型列表,然后为每个文档类型进行Web服务调用.我想立刻制作这些,所以循环它们只需要最长的一个.我不知道我的代码是否正确,我还需要做其他事情,或者我的代码是不正确的.
行动:
public ActionResult GetPlan(MemberViewModel request)
{
DocService ds = new DocService();
List<DocType> docTypes = ds.GetDocTypesForPlan(request.PlanId);
List<CoverageDocument> coverageDocuments = ds.GetDocumentsForDocTypes(docTypes);
return View(coverageDocuments);
}
Run Code Online (Sandbox Code Playgroud)
GetDocumentsForDocTypes:
public List<CoverageDocument> GetDocumentsForDocTypes(List<DocType> planDocTypes)
{
List<CoverageDocument> planDocuments = new List<CoverageDocument>();
DocumentUtility documentUtility = new DocumentUtility();
int lastYear = DateTime.Now.Year - 1;
planDocTypes.ForEach(async (docType) =>
{
DocumentUtility.SearchCriteria sc = new DocumentUtility.SearchCriteria();
sc.documentType = docType;
Dictionary<long, Tuple<string, string>> documentList = await documentUtility.FindDocuments(sc);
documentList.ToList().ForEach((document) =>
{
CoverageDocument doc = this.coverageDocumentConstructor(document);
planDocuments.Add(doc);
});
});
return planDocuments;
}
Run Code Online (Sandbox Code Playgroud)
例外:
附加信息:此时无法启动异步操作.异步操作只能在异步处理程序或模块中启动,或者在页面生命周期中的某些事件中启动.如果在执行页面时发生此异常,请确保将页面标记为<%@ Page Async ="true"%>.此异常还可能表示尝试调用"异步void"方法,该方法通常在ASP.NET请求处理中不受支持.相反,异步方法应该返回一个Task,调用者应该等待它.
您的代码不正确.通过向ForEach扩展方法发送异步lambda,你强迫它async void在UI事件处理程序之外永远不是一个好主意.
要实际异步,您的调用需要始终保持异步:
public async Task<ActionResult> GetPlan(MemberViewModel request)
{
DocService ds = new DocService();
List<DocType> docTypes = ds.GetDocTypesForPlan(request.PlanId);
List<CoverageDocument> coverageDocuments = await ds.GetDocumentsForDocTypesAsync(docTypes);
return View(coverageDocuments);
}
public async Task<List<CoverageDocument>> GetDocumentsForDocTypesAsync(List<DocType> planDocTypes)
{
DocumentUtility documentUtility = new DocumentUtility();
int lastYear = DateTime.Now.Year - 1;
var planDocuments = await Task.WhenAll(planDocTypes.Select(async (docType) =>
{
DocumentUtility.SearchCriteria sc = new DocumentUtility.SearchCriteria();
sc.documentType = docType;
return await documentUtility.FindDocuments(sc).Select((document) => this.coverageDocumentConstructor(document))
}));
return planDocuments.SelectMany(doc => doc);;
}
Run Code Online (Sandbox Code Playgroud)