【问题标题】:Can't await async extension method无法等待异步扩展方法
【发布时间】:2013-11-12 17:15:14
【问题描述】:

情况很简单——我写了一个扩展方法并使它与返回类型Task<T>异步。但是当我尝试使用 await 调用它时,编译器会抛出一个错误,表明扩展方法根本没有被识别为异步。 这是我的代码:

public static async Task<NodeReference<T>> CreateWithLabel<T>(this GraphClient client, T source, String label) where T: class
    {
        var node = client.Create(source);
        var url = string.Format(ConfigurationManager.AppSettings[configKey] + "/node/{0}/labels", node.Id);
        var serializedLabel = string.Empty;
        using (var tempStream = new MemoryStream())
        {
            new DataContractJsonSerializer(label.GetType()).WriteObject(tempStream, label);
            serializedLabel = Encoding.Default.GetString(tempStream.ToArray());
        }
        var bytes = Encoding.Default.GetBytes(serializedLabel);

        using (var webClient = new WebClient())
        {
            webClient.Headers.Add("Content-Type", "application/json");
            webClient.Headers.Add("Accept", "application/json; charset=UTF-8");
            await webClient.UploadDataTaskAsync(url, "POST", bytes);
        }

        return node;
    }


var newNode = await client.CreateWithLabel(new Task(), "Task");

确切的错误信息是这样的:

“await”运算符只能在异步方法中使用。考虑使用 'async' 修饰符标记此方法并将其返回类型更改为 'Task'

我做错了什么还是语言/编译器限制?

【问题讨论】:

  • 请贴出代码。
  • 提示:如果您关注TAP conventions,其他开发人员将更容易使用您的async 方法。

标签: c# .net extension-methods async-await c#-5.0


【解决方案1】:

错误信息很清楚:你调用扩展方法的方法where应该标记为async。

public Task<string> MyExtension(this string s) { ... }

public async Task MyCallingMethod()
{    
    string result = await "hi".MyExtension();
}

现在重新阅读这部分应该更有意义:

“'await' 运算符只能在内异步方法中使用。”

【讨论】:

  • 我明白了。下次会更细心。
  • @dcastro,您可能希望更改MyCallingMethod 的签名以返回Task,void 仅适用于异步事件处理程序。
  • @Noseratio 我不同意,还有很多其他场景你想要“一劳永逸”的行为。不过我会编辑我的帖子,只是因为经验不足的用户可能会对async void 的结果感到惊讶。
  • @dcastro,我也不同意有很多。我有兴趣了解async event handlers 以外的任何有用场景(这里显然不是这种情况)。
  • 记录,例如。服务可能想要触发一个方法并触发一些业务逻辑,但会尽快返回给客户端。您并不总是需要等待方法的结果。也许“plenty”这个词有点过头了,但是说“void 只对异步事件处理程序有用”也不正确。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多