WebAPI:' IHttpActionResult'不包含' GetAwaiter'

时间:2016-08-09 11:21:44

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

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

  

Layer1 / Controllers< ===> 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&#39; IHttpActionResult&#39;不包含&#39; GetAwaiter&#39;的定义没有扩展方法&#39; GetAwaiter&#39;接受第一个类型&#39; IHttpActionResult&#39;可以找到(你错过了使用指令或程序集引用吗?)

尝试另一种方法,我尝试为异步创建一个新的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&#39; OkNegotiatedContentResult&#39;不包含&#39; GetAwaiter&#39;的定义没有扩展方法&#39; GetAwaiter&#39;接受类型&#39; OkNegotiatedContentResult&#39;的第一个参数。可以找到(你错过了使用指令或程序集引用吗?)

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

1 个答案:

答案 0 :(得分:0)

异常消息说明您正在尝试返回无法等待的内容。 await不需要返回Task。除非在方法中确实需要异步功能,否则只需使用Task

返回Task.FromResult即可

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

  

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

使用您的第一次尝试,可以对此进行重构......

[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);
    });
}