繁体   English   中英

使用 await 同步调用 async 方法

[英]Call async method synchronously with await

我正在为授权调用异步方法 (LoginAsync)。

 UserObject = clienAuthenticationService.LoginAsync(sUser).Result;
 if (UserObject != null)
 {
    // Proceed for further code;
 }
 else
 {
    // Show Error message of failed authentication;
 }

由于这是第三方服务,在我 go 到下一行之前,我需要 LoginAsync 的 output(如果块)。 当前代码对我来说工作正常,我知道它会等到执行 LoginAsync。

但是,我收到了将 'Task.Result' 的使用替换为 'await' 的建议。

问题:我不确定我的案例是否与等待相关,因为我需要同步执行异步方法。 有人可以确认给我的建议是否与我的情况无关,或者有办法与 await 同步调用异步方法吗?

编辑:发表评论后,我修改了我的代码以添加 await 而不是 .Result。 仍然无法从异步方法读取响应。 下面是新代码

public static async Task<bool> CallJimService(LoginUserClass sUser)
{

    var result = clientJIMServiceCall.LoginAsync(sUser).ConfigureAwait(false);
  
    LoginUserClass loginUserDetails = await result;

    if (loginUserDetails != null && loginUserDetails.UserProperties != null && loginUserDetails.UserProperties.LoggedIn)
    {
        return true;
    }
    else
    {
        return false;
    }
  
 }
 
 
 
  public static Boolean ValidateUserCredentails(string pstrUserName, string pstrPassWord)
  {
        LoginUserClass sUser = new LoginUserClass();
        sUser.UserName = pstrUserName;
        sUser.Password = pstrPassWord;
        
        return CallJimService(sUser).Result; // Here I want to avoid using .Result.
  }

另外,我不想将 ValidateUserCredentails() 更改为异步。 我怎样才能度过难关?

LoginAsync方法被标记为异步,并返回一个Task 此方法应具有异步实现。 您不能同步执行此方法,因为此方法没有同步实现 如果您使用的 class 将提供登录操作的同步实现,他们将不得不公开一个Login方法。

无法保证异步调用此方法将导致异步操作。 如果 state 需要,异步方法可以同步返回。 例如,如果您已经登录, AsyncLogin可能会同步返回。但是,除非做一些非常具体的事情,否则方法中必须至少有一个执行路径需要一些异步操作。

给你的推荐并非无关紧要。

您不应阻止异步操作,尤其是使用Task.Result 异步操作不涉及多线程,等待Task.Result可能会导致应用程序死锁,因为您的线程将等待 Result 并且无法响应异步操作信号完成。

您宁愿异步等待LoginAsync方法,也使您的方法异步。

如果您被迫从同步上下文调用LoginAsync方法,则正确的实现将取决于您尝试实现的确切目标以及LoginAsync方法的作用。

如果您能够使用 await(也就是说,如果您已经在异步方法中),则使用 await。

UserObject = await clienAuthenticationService.LoginAsync(sUser);

使用 await 有助于代码同步运行(即它保留控制流)。 我将尝试通过以下示例来解释异步用法,该示例具有异步执行流程,但同步控制流程 - 以下代码运行不同步(即异步) -

// Authenticate the user, but don't wait here while authenticating.
// Async part could be - Checking database for user details. (Network IO operation)
var UserAuthTask = LoginAsync();

// Prepare a layout or something to show when authentication fails. Don't show yet.
// Again, don't wait while preparing.
// Async part could be -  Reading a render template file. (File IO operation)
var AuthFailScreen = PrepareFailScreenAsync();

// Similar to failure screen.
var AuthSuccessScreen = PrepareSuccessScreenAsync();

现在,我们使用 await 来根据自己的喜好同步流程 -

var UserAuthResult = await UserAuthTask;
if (UserAuthResult.Success)
{
    var SuccessScreen = await AuthSuccessScreen;
    SuccessScreen.Show();
}
else
{
    var FailScreen = await AuthFailScreen;
    FailScreen.Show();
}

您可以等待之前的每个任务,例如var UserAuthTask = await LoginAsync(); ,但是你会失去做多件事的好处,而这些事情本可以在认证时完成。 我不确定异常处理,但异步和同步代码的混合和匹配可能会导致问题。

如果我在任何时候错了,请纠正我。 谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM