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


  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'IHttpActionResult'不包含'GetAwaiter'的定义,并且找不到扩展方法'GetAwaiter'接受类型为'IHttpActionResult'的第一个参数(是否缺少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'的定义,并且找不到扩展方法'GetAwaiter'接受类型为'OkNegotiatedContentResult'的第一个参数(是否缺少using指令或程序集引用?)


有什么解决办法吗?希望有人能帮助我。

最佳答案

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

引用本文:http://blog.stephencleary.com/2012/02/async-and-await.html


  提示:如果您有一个非常简单的异步方法,则可以
  不使用await关键字(例如,使用
  Task.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);
    });
}

10-01 12:47