【问题标题】:C#, return a string from a function that calls another async function?C#,从调用另一个异步函数的函数返回一个字符串?
【发布时间】:2017-02-14 02:24:24
【问题描述】:

我想从调用另一个异步函数的函数中返回一个字符串。你能告诉我这是否可能吗? 这是我的功能

public async Task<TokenCredential> LoginAsync()
{
    var credential = await GenerateCredentialAsync(); // This is a library function 
                                                   //that returns a 'Task<TokenCredential>'

    return credential.Token; // I want to return this value which is a string
}

我只想返回令牌值。但是如果我改变返回类型。我得到一个编译器错误

"await 运算符只能在异步方法中使用"

.

如果我像下面这样完全删除等待:

public string LoginAsync()
{
    var credential = GenerateCredentialAsync();            
    return credential.Token;
}

尝试取消引用 credential.token 时出现此错误

'Task 不包含 Token 的定义。

你能帮忙吗?

【问题讨论】:

  • Token 是什么类型?如果您使用return async Task&lt;tokentype&gt; 而不是Task&lt;TokenCredential&gt;,您的第一个版本就可以使用。
  • 以上没有多少意义,你的方法标有async,但你说使用await时出错,上面也没有匿名类或代码。
  • 这里的实际问题是什么,你不能从异步方法返回 just 令牌值,你必须返回一个最终将包含令牌的任务,因此返回类型的Task&lt;T&gt;。在使用async 时,您必须使用此返回类型(或void)。
  • 另外,如果你不知道自己在做什么,你不应该尝试将异步方法包装在同步包装器中,这总是会导致死锁等问题。

标签: c# .net asynchronous async-await


【解决方案1】:

如果凭据的Token 属性返回TokenCredential,则方法的返回类型实际上应该是Task&lt;TokenCredential&gt;。如果 Token 属性返回 string,则方法的返回类型应为 Task&lt;string&gt;。到目前为止一切顺利。

问题可能在于您如何调用LoginAsync() 方法。由于这是一个异步,你应该等待它:

TokenCredential token = await LoginAsync();

这要求您从标记为 async 的方法中调用它。

如果将LoginAsync 方法定义为同步方法,则需要在从LoginAsync() 方法返回之前获取GenerateCredentialAsync() 的结果。您可以通过阻止返回的TaskResult 属性来做到这一点:

public string LoginAsync()
{
    var credential = GenerateCredentialAsync().Result;            
    return credential.Token;
}

请注意,不建议使用后一种方法。请参阅 Stephen Cleary 的博客文章,了解有关为什么不应该阻塞异步代码的更多信息:http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

【讨论】:

    【解决方案2】:

    听起来您在某处缺少异步声明。

    你上面的代码:

    public async Task<TokenCredential> LoginAsync()
    {
        var credential = await GenerateCredentialAsync(); // This is a library function that returns a 'Task<TokenCredential>'
    
        return credential.Token; // I want to return this value which is a string
    }
    

    100% 正确(假设 GenerateCredentialAsync 包含返回“TokenCredential”的属性“Token”

    您可能遇到的问题是无论调用 LoginAsync 都缺少“异步”声明。

    除非您处于标记为异步的方法中,否则您不能“​​等待”某事

    一般规则是您需要将“链”中的每个方法都标记为异步。

    【讨论】:

      【解决方案3】:

      您应该使用 TokenCredential.Token 的类型作为 Task 中的返回类型。

      如果 TokenCredential.Token 是字符串类型,你应该有:

      public async Task<string> LoginAsync()
      

      问候

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-17
        • 2013-12-08
        • 2013-04-14
        相关资源
        最近更新 更多