【问题标题】:WebAPI : 'IHttpActionResult' does not contain a definition for 'GetAwaiter'WebAPI:“IHttpActionResult”不包含“GetAwaiter”的定义
【发布时间】:2016-12-15 09:59:05
【问题描述】:

早上好,这是我在社区的第一个问题。我正在使用 C# WebAPI 框架,并且正在尝试将所有控制器的方法更改为异步。我的控制器从 GenericController 扩展而来,它有一个方法 (CallWF),可以从 DLL 中调用方法,并且还可以处理各种异常。

Layer1/控制器 Layer2/GenericController.CallWF Layer3/DLL 方法

这是我的 GenericController.CallWF 代码:

protected IHttpActionResult CallWF<T>(Func<T> action)
{
    try
    {
        return Ok(action.Invoke());
    }
    catch (Exception e1)
    {
        return( BadRequest( GetMyExceptionMessage(e1)) );
    }
}

protected IHttpActionResult CallWF(Action action)
{
    try
    {
        action.Invoke();
        return Ok();
    }
    catch (Exception e1)
    {
        return( BadRequest( GetMyExceptionMessage(e1)) );
    }
}

这是控制器方法的示例。

[ResponseType(typeof(string))]
[Route("MyMethodA")]
public IHttpActionResult MyMethodA(int arg1)
{
    return CallWF<string>(
    () => {
        return repositoryA.itsMethodA(arg1);
    });
}

如您所见,该方法是同步的。现在我想把它变成异步的。在阅读了一些解释如何制作异步函数的网站后,我认为这是解决方案。

[ResponseType(typeof(string))]
[Route("MyMethodA")]
public async Task<IHttpActionResult> MyMethodA(int arg1)
{
    return await CallWF<string>(
    () => {
        return repositoryA.itsMethodA(arg1);
    });
}

但是这样做,会出现以下错误:

CS1061“IHttpActionResult”不包含“GetAwaiter”的定义,并且找不到接受“IHttpActionResult”类型的第一个参数的扩展方法“GetAwaiter”(您是否缺少 using 指令或程序集引用?)

尝试另一种方法,我尝试为异步创建一个新的 CallWF 函数。 这是采用的方法。

protected async Task<IHttpActionResult> CallWFAsync<T>(Func<T> action)
{
    try
    {
        IHttpActionResult res = Ok( action.Invoke());
        return await Ok( action.Invoke() );
    }
    catch (Exception e1)
    {
       return ( BadRequest(GetMyExceptionMessage(e1)) );
    }
}

这样做会导致标题错误。

CS1061“OkNegotiatedContentResult”不包含“GetAwaiter”的定义,并且找不到接受“OkNegotiatedContentResult”类型的第一个参数的扩展方法“GetAwaiter”(您是否缺少 using 指令或程序集引用?)

有解决这个问题的想法吗?希望有人可以帮助我。

【问题讨论】:

  • 异常消息说明您正在尝试返回无法等待的内容。不需要await,只需返回Task。除非方法中实际需要异步功能,否则您可以简单地返回 Task。你可以使用Task.FromResult

标签: c# generics asynchronous asp.net-web-api lambda


【解决方案1】:

异常消息说明您正在尝试返回不可等待的内容。不需要await,只需返回Task。除非方法中实际需要异步功能,否则您可以使用 Task.FromResult 简单地返回 Task

参考这篇文章:http://blog.stephencleary.com/2012/02/async-and-await.html

提示:如果你有一个非常简单的异步方法,你也许可以 在不使用 await 关键字的情况下编写它(例如,使用 任务.FromResult)。如果您可以在没有等待的情况下编写它,那么您应该 无需等待即可编写它,并从方法中删除 async 关键字。 返回 Task.FromResult 的非异步方法比 异步方法返回一个值。

使用您的第一次尝试,可以将其重构为...

[ResponseType(typeof(string))]
[Route("MyMethodA")]
public Task<IHttpActionResult> MyMethodA(int arg1) {
    var result = CallWF<string>(
    () => {
        return repositoryA.itsMethodA(arg1);
    });

    return Task.FromResult(result);
}

在您的第二种方法中,如果您想转换 CallWF 方法,您可以使用相同的方法

protected Task<IHttpActionResult> CallWFAsync<T>(Func<T> action) {
    IHttpActionResult result = null;
    try
    {
        result = Ok(action.Invoke());
    } catch (Exception e1) {
        result = BadRequest(GetMyExceptionMessage(e1));
    }
    return Task.FromResult(result);
}

现在这将允许您通过调用 CallWFAsync 方法来执行第一个示例中尝试执行的操作

[ResponseType(typeof(string))]
[Route("MyMethodA")]
public async Task<IHttpActionResult> MyMethodA(int arg1)
{
    return await CallWFAsync<string>(
    () => {
        return repositoryA.itsMethodA(arg1);
    });
}

【讨论】:

  • 你说的一切都有效。首先,我被告知所有存储库的方法都是同步的,所以很明显我不需要创建一个辅助方法来处理。然后我试试你的代码,它可以工作。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
  • 2017-04-20
  • 2017-11-20
  • 2018-08-21
  • 2017-04-08
  • 1970-01-01
  • 2023-01-09
相关资源
最近更新 更多