在我的服务层中,我想异步触发多个方法并等待其结果。
我一次尝试一个,这是错误的。
在我的服务类中,我调用了类似
的方法var _validChapterCodesTask = gd.validateChapterCodeDetails(_input1);
await Task.WhenAll(_validChapterCodesTask);
var _chapterCodeResult = await _validChapterCodesTask;
在 DAL类中,方法定义类似于
public async Task<IEnumerable<ChapterCodeValidationOutput>> validateChapterCodeDetails(GroupMembershipValidationInput gmvi)
{
Repository rep = new Repository();
if (!gmvi._chapterCodes.All(x => x.Equals("")))
{
var _validChapterCodes = await rep.ExecuteStoredProcedureAsync<Entities.Upload.ChapterCodeValidationOutput>(SQL.Upload.UploadValidation.getChapterCodeValidationSQL(gmvi._chapterCodes),null);
return _validChapterCodes;
}
else
return new List<ChapterCodeValidationOutput>();
}
错误消息
第错误208
await
运算符只能在async
方法中使用。请考虑使用async
修饰符标记此方法,并将其返回类型更改为Task<ARC.Donor.Business.Upload.GroupMembershipValidationOutput>
。C:\Users\m1034699\Desktop\Stuart_Upgrade_2.1_New Approach\Stuart_Export_Upload_v2.1\Stuart Web Service\ARC.Donor.Service\Upload\UploadValidationServices.cs 34 13 ARC.Donor.Service
行
await Task.WhenAll(_validChapterCodesTask);
var _chapterCodeResult = await _validChapterCodesTask;
我做错了什么?
答案 0 :(得分:1)
错误消息非常明确。它告诉您,您服务类方法错误地尝试使用async
关键字。为了解决这个问题,您应该使用Stephen Cleary在MSDN上发布的"Async all the way"作为最佳做法。
例如,如果您的服务类具有使用Task
或Task<T>
的方法正文,或尝试使用await
关键字,则此方法签名对应此方法正文必须为async
(因为async
关键字允许方法使用await
关键字)。此外,此方法本身也应该Task
或Task<T>
返回,该规则的例外情况非常少。
就个人而言,我会改变你的 DAL 类,只是返回代表异步工作的操作而不实际等待它。如果你考虑一下,validateChapterCodeDetails
方法的主体不实际上需要对结果做任何事情,它只需要返回它们(而不是在那里实现它们)。请考虑以下事项:
public Task<IEnumerable<ChapterCodeValidationOutput>>
validateChapterCodeDetails(GroupMembershipValidationInput gmvi)
{
var rep = new Repository();
return gmvi._chapterCodes.All(x => x.Equals(""))
? new List<ChapterCodeValidationOutput>()
: rep.ExecuteStoredProcedureAsync
<Entities.Upload.ChapterCodeValidationOutput>
(SQL.Upload.UploadValidation
.getChapterCodeValidationSQL(gmvi._chapterCodes),null)
}
由于您已经等待Task<IEnumerable<ChapterCodeValidationOutput>>
变量,因此您可以访问.Result
属性以获取您要查找的内容。
然后在服务类中,您的方法将如下所示:
public async Task ConsumeAsync()
{
var _validChapterCodesTask = gd.validateChapterCodeDetails(_input1);
await Task.WhenAll(_validChapterCodesTask);
var _chapterCodeResult = _validChapterCodesTask.Result;
// Do something with it...
}
Here is a .NET fiddle应该有助于更好地为您举例说明。
注意强>
我还要谨慎使用IEnumerable
因为它与你的回购有关,你应该确保数据库的结果不会通过延期执行发生,否则你冒着连接问题的风险,即;无意中断开连接,或者没有正确关闭连接。
答案 1 :(得分:0)
在您致电的Service
班级
var _validChapterCodesTask = gd.validateChapterCodeDetails(_input1);
await Task.WhenAll(_validChapterCodesTask);
var _chapterCodeResult = await _validChapterCodesTask;
在方法签名中添加async
,其中await Task.WhenAll(_validChapterCodesTask);
被调用。当此方法也有返回类型时,您必须将此类型包装在Task
中,如异常所示:
Task<ARC.Donor.Business.Upload.GroupMembershipValidationOutput>
E.g。如果你有以下方法:
public GroupMemberShipValidationOutput validate(..) {
...
await Task.WhenAll(_validChapterCodesTask);
...
}
您必须将方法签名更改为:
public async Task<GroupMemberShipValidationOutput> validate(..) {
...
await Task.WhenAll(_validChapterCodesTask);
...
}