所以我在我的基本控制器中有这个方法:
protected async Task<KeyValuePair<bool, string>> ExecuteSimpleQuery(Func<Task<bool>> service)
{
var success = false;
var message = string.Empty;
try
{
success = await service.Invoke();
}
catch (Exception exception)
{
message = exception.Message;
success = false;
}
return new KeyValuePair<bool, string>(success, message);
}
我想这样用:
public async Task<ActionResult> Login(RegisterDto register)
{
var objectStore =
await this.ExecuteSimpleQuery(async () => await this.securityService.LoginAsync(register.UserName, register.Password, true));
if (objectStore.Key)
{
return this.RedirectToAction("Index", "Toolbox");
}
this.TempData["error"] = objectStore.Value;
return this.View(register);
}
所以我传递给ExecuteSimpleQuery
的是awaitable
方法LoginAsync
,我只是想确保我正在等待该方法。
我的思维过程是:
LoginAsync
会返回Task<bool>
,因此Func
必须返回该内容。await
,也可以。Func
在Task<bool>
内返回ExecuteSimpleQuery
,您可以await
在那里,所以应该ExecuteSimpleQuery
正在等待某个方法,因此必须拥有async
关键字,因此必须返回Task<T>
。Login
操作,该方法返回Task<T>
,因此可以等待它。我甚至关闭了吗?
答案 0 :(得分:2)
这会奏效。它可以简化一点:
async () => await this.securityService.LoginAsync(register.UserName, register.Password, true)
可以写成
() => this.securityService.LoginAsync(register.UserName, register.Password, true)
因为LoginAsync已经返回Task
。这就是说,每当你处理任务时总是在等待它们具有一定的一致性。以你的方式包装这个任务并不是真的有害。我认为两种方式都是合理的。
如果LoginAsync
无法抛出任何异常(您关心的话),则根本不需要lambda。当您调用异步方法时,异常通常存储在Task
中。您可以直接将Task
传递给ExecuteSimpleQuery
。如果LoginAsync
不符合此模式,则无法执行此操作,因为异常会过早触发。
var loginTask = securityService.LoginAsync(register.UserName, register.Password, true);
var objectStore = await ExecuteSimpleQuery(loginTask);
protected async Task<KeyValuePair<bool, string>> ExecuteSimpleQuery(Task<bool> service)
{
//...
try
{
success = await service;
}
catch (Exception exception)
{
//...
}
//...
}
您可以通过说:
来测试 var loginTask = Task.Run(() => { throw null; });
catch
会被点击。