早上好,这是我在社区中的第一个问题。我正在使用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);
});
}