早上好,这是我在社区的第一个问题。我正在使用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;的第一个参数。可以找到(你错过了使用指令或程序集引用吗?)
有什么想法可以解决这个问题?希望有人可以帮助我。
答案 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);
});
}