在没有等待#2的情况下调用异步方法

Cat*_*lin 42 c# asp.net asynchronous async-await c#-5.0

我有一个异步方法:

public async Task<bool> ValidateRequestAsync(string userName, string password)
{
    using (HttpClient client = new HttpClient())
    {
        HttpResponseMessage response = await client.GetAsync(url);
        string stringResponse = await response.Content.ReadAsStringAsync();

        return bool.Parse(stringResponse);
    }
}
Run Code Online (Sandbox Code Playgroud)

我这样称呼这个方法:

bool isValid = await ValidateRequestAsync("user1", "pass1");
Run Code Online (Sandbox Code Playgroud)

我可以从同步方法调用相同的方法,而不使用await关键字?

例如:

public bool ValidateRequest(string userName, string password)
{
    return ValidateRequestAsync(userName, password).Result;
}
Run Code Online (Sandbox Code Playgroud)

我认为这会导致僵局.

编辑

调用上面的方法会使调用永远不会结束.(该方法不再到达终点)

Kri*_*ten 64

如果从单线程执行上下文(如UI线程)调用异步方法,并等待同步结果,则死锁的可能性很高.在你的例子中,这个概率是100%

想一想.你打电话后会发生什么

ValidateRequestAsync(userName, password).Result
Run Code Online (Sandbox Code Playgroud)

您调用方法ValidateRequestAsync.在那里你调用ReadAsStringAsync.结果是,任务将返回到UI线程,并且计划继续在UI线程可用时继续执行.但是,当然,它永远不可用,因为它正在等待(阻止)完成任务.但是任务无法完成,因为它正在等待UI线程变得可用.僵局.

有办法防止这种僵局,但它们都是一个坏主意.为了完整起见,以下可能有效:

Task.Run(async () => await ValidateRequestAsync(userName, password)).Result;
Run Code Online (Sandbox Code Playgroud)

这是一个坏主意,因为你仍然阻止你的UI线程等待并且没有任何用处.

那么解决方案是什么呢?一路走异步.UI线程上的原始调用者可能是一些事件处理程序,因此请确保它是异步的.

  • 不,`task.ConfigureAwait(false).Result`当然不行.它甚至不会编译,因为`ConfigureAwait()`不返回`Task`. (2认同)

sav*_*nda 5

您可以使用return ValidateRequestAsync(userName,password).GetAwaiter()。GetResult();

  • 这似乎不起作用。该进程挂起,就像您执行 ValidateRequestAsync(userName, password).Result 一样。Kris 响应的“坏主意”解决了这个问题: Task.Run(async () =&gt; wait ValidateRequestAsync(userName, password)).Result (4认同)