[英]How to call one async method from another one in ASP.NET Web API application
因此,我在ASP.NET Web API应用程序中具有以下带有异步方法的程序流程:API控制器调用一个异步方法(我们将其称为asyncMethod1 ),该方法需要第二个异步方法(我们将其称为asyncMethod2 )中的内容。 API控制器实际上不需要知道asyncMethod1何时完成,尽管这样可以很好地为用户提供反馈。 另一方面,asyncMethod1确实需要知道asyncMethod2何时完成。
以下是相关代码:
public class MyController : ApiController
{
private CustomClass customClass;
public IHttpActionResult WorkMethod(TestObject testObject)
{
Debug.WriteLine("WorkMethod - before calling asyncMethod1");
Task.Run(async () => await this.asyncMethod1(testObject)).Wait(); // ERROR HERE
Debug.WriteLine("WorkMethod - after calling asyncMethod1");
return Ok();
}
private async Task asyncMethod1(TestObject testObject)
{
Debug.WriteLine("asyncMethod1 - before calling asyncMethod2");
Dictionary<string, string> x = await this.asyncMethod2(testObject);
Debug.WriteLine("asyncMethod1 - after calling asyncMethod2");
try
{
using (Task<IList<TestResponse>> testTask = customClass.DoAsyncWork1(x))
{
IList<TestResponse> response = await testTask;
// Do something with response
Debug.WriteLine("Transform 'response'");
}
}
catch (Exception ex)
{
throw new Exception(" Exception ", ex);
}
}
private async Task<Dictionary<string, string>> asyncMethod2(TestObject testObject)
{
try
{
Debug.WriteLine("asyncMethod2 - before calling DoAsyncWork2");
using (Task<IList<SomeData>> workTask = customClass.DoAsyncWork2(testObject.x))
{
IList<SomeData> data = await workTask ;
var output = new Dictionary<string, string>();
output = data.values;
Debug.WriteLine("asyncMethod2 - returning data to caller");
return output;
}
}
catch (Exception ex)
{
throw new Exception(" Exception ", ex);
}
}
}
CustomClass是我正在使用的自定义API中的类,其中方法DoAsyncWork1和DoAsyncWork2都是异步的。
当上面的代码运行时,我在方法WorkMethod中获得以下异常,该行Task.Run(async () => await this.asyncMethod1(testObject)).Wait();
:
“ Message”:“发生错误。”,“ ExceptionMessage”:“发生一个或多个错误。”,“ ExceptionType”:“ System.AggregateException”,“ StackTrace”:“在
System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
在System.Threading.Tasks.Task.Wait(Int32毫秒超时,CancellationToken cancelToken)
在System.Threading.Tasks.Task.Wait()
在MyController.cs:第9行的MyController.WorkMethod(Test testObject)中
在lambda_method(Closure,Object,Object [])
在System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor处。<> c__DisplayClass10.b__9(对象实例,对象[] methodParameters)
在System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute处(对象实例,Object []参数)
在System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext,IDictionary`2 arguments,CancellationToken cancelToken)
输出如下:
WorkMethod-调用asyncMethod1之前
asyncMethod1-调用asyncMethod2之前
asyncMethod2-调用DoAsyncWork2之前
asyncMethod2-将数据返回给调用方
asyncMethod1-调用asyncMethod2之后
如果在方法WorkMethod中,我对此进行了更改:
Task.Run(async () => await this.asyncMethod1(asyncMethod1)).Wait();
对此:
var task = this.asyncMethod1(asyncMethod1);
Debug.WriteLine("WorkMethod - after calling asyncMethod1");
task.wait();
我没有遇到异常,但是程序流从未到达asyncMethod1的地步 ,它无法处理从asyncMethod2返回的响应。 另外,输出如下:
WorkMethod-调用asyncMethod1之前
asyncMethod1-调用asyncMethod2之前
asyncMethod2-调用DoAsyncWork2之前
WorkMethod-调用asyncMethod1之后
这里有什么问题? 什么是我要实现的正确方法,即从API控制器调用异步方法,然后从第一个方法调用第二个异步方法?
您在评论中说:
在链的某个点上,您必须有一个非异步方法,对吗?
答案是否定的。 一切都可以是异步的。 因此,您可以将其作为操作:
public async Tack<IHttpActionResult> WorkMethod(TestObject testObject)
{
Debug.WriteLine("WorkMethod - before calling asyncMethod1");
await this.asyncMethod1(testObject);
Debug.WriteLine("WorkMethod - after calling asyncMethod1");
return Ok();
}
然后进行这种处理会使该方法毫无意义。 您可以使asyncMethod1
成为实际的操作方法。 如果你想。
就是说,您得到的异常是因为实际上存在异常。 但是,因为您没有await
结果,所以它会作为AggregateException
抛出,并带有InnerExceptions
集合内的实际异常。 await
任务后,您将看到抛出的实际异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.