luk*_*egf 2 c# asp.net async-await asp.net-web-api
所以,我有在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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
CustomClass是我正在使用的自定义API中的一个类,其中DoAsyncWork1和DoAsyncWork2方法都是异步的.
当上面的代码运行时,我在方法WorkMethod,line中得到以下异常Task.Run(async () => await this.asyncMethod1(testObject)).Wait();:
"消息": "发生了错误.", "ExceptionMessage": "一个或多个错误的发生.", "ExceptionType": "System.AggregateException", "堆栈跟踪":"在
System.Threading.Tasks.Task.ThrowIfExceptional (布尔includeTaskCanceledExceptions)
在System.Threading.Tasks.Task.Wait(的Int32 millisecondsTimeout,的CancellationToken的CancellationToken)
在System.Threading.Tasks.Task.Wait()
在MyController.WorkMethod(试验的TestObject)在MyController.cs:管线9
在lambda_method (封闭,对象,对象[])
在System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<> c__DisplayClass10.b__9(Object实例,对象[] methodParameters)
在System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute (Object实例,对象[]参数)
在System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext,IDictionary`2参数,的CancellationToken的CancellationToken)
输出如下:
WorkMethod -调用asyncMethod1之前
调用asyncMethod2前- asyncMethod1
调用DoAsyncWork2前- asyncMethod2
asyncMethod2 -将数据返回给呼叫方
asyncMethod1 -调用asyncMethod2后
如果,在方法WorkMethod我改变了这个:
Task.Run(async () => await this.asyncMethod1(asyncMethod1)).Wait();
Run Code Online (Sandbox Code Playgroud)
对此:
var task = this.asyncMethod1(asyncMethod1);
Debug.WriteLine("WorkMethod - after calling asyncMethod1");
task.wait();
Run Code Online (Sandbox Code Playgroud)
我没有得到异常,但程序流程永远不会到达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();
}
Run Code Online (Sandbox Code Playgroud)
那样做那种方法毫无意义.您可以制作asyncMethod1实际的操作方法.如果你想.
也就是说,你得到的例外是因为实际上存在异常.但是因为你没有await得到结果,所以它会AggregateException在InnerExceptions集合中被抛出一个真正的异常.一旦你await的任务,你会看到抛出的真正的异常.
| 归档时间: |
|
| 查看次数: |
837 次 |
| 最近记录: |