Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 传播的异步/等待方法调用_C#_.net_Asynchronous - Fatal编程技术网

C# 传播的异步/等待方法调用

C# 传播的异步/等待方法调用,c#,.net,asynchronous,C#,.net,Asynchronous,因此,我的基本控制器中有此方法: protected async Task<KeyValuePair<bool, string>> ExecuteSimpleQuery(Func<Task<bool>> service) { var success = false; var message = string.Empty; try { success = await service.Invoke();

因此,我的基本控制器中有此方法:

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);
}
受保护的异步任务执行示例查询(Func服务)
{
var成功=false;
var message=string.Empty;
尝试
{
success=wait service.Invoke();
}
捕获(异常)
{
message=exception.message;
成功=错误;
}
返回新的KeyValuePair(成功,消息);
}
我想这样使用它:

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);
}
public异步任务登录(RegisterDto注册)
{
var对象存储=
等待this.ExecuteSimpleQuery(异步()=>等待this.securityService.LoginAsync(register.UserName,register.Password,true));
if(objectStore.Key)
{
返回此.RedirectToAction(“索引”、“工具箱”);
}
this.TempData[“error”]=objectStore.Value;
返回此。查看(注册);
}
因此,我要传递给
ExecuteSimpleQuery
的是一个
可等待的
方法
LoginAsync
,我只想确保我正确地等待该方法

我的思考过程是:

  • LoginAsync
    返回一个
    任务
    ,因此
    Func
    必须返回该任务
  • 当传递它时,您可以等待它,也可以这样做
  • 因为
    Func
    ExecuteSimpleQuery
    中返回一个
    Task
    ,所以您可以
    在那里等待它,也应该如此
  • ExecuteSimpleQuery
    正在等待一个方法,因此必须有
    async
    关键字,因此必须返回
    Task
  • 最后一点传播到
    登录
    操作,该方法返回
    任务
    ,因此可以等待,也应该等待

  • 我就差一点了吗?

    这就行了。它可以简化一点:

    async () => await this.securityService.LoginAsync(register.UserName, register.Password, true)
    
    可以写成

    () => this.securityService.LoginAsync(register.UserName, register.Password, true)
    
    因为LoginAsync已经返回了一个
    任务
    。也就是说,无论何时处理任务,总是等待任务都具有一定的一致性。用你的方式来完成这项任务并没有什么害处。我认为这两种方法都是合理的

    如果
    LoginAsync
    无法抛出任何异常(您关心的),则根本不需要lambda。调用异步方法时,异常通常存储在
    任务中。您可以直接将
    任务
    传递给
    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)
        {
            //...
        }
    
        //...
    }
    

    catch
    将被命中。

    为什么这么复杂?您将登录调用委托给谁执行SampleQuery?使用基于服务的体系结构,我有一种真正一致的调用服务的方法,因此,我不必一直写
    try…catch
    ,而是写一次,每次都处理相同的问题。只是简单多了,没那么乏味
       var loginTask = Task.Run(() => { throw null; });