jga*_*fin 1 c# async-await asp.net-web-api2
我有一个控制器方法,它看起来像这样:
[HttpPut, Route("cqs/command")]
public HttpResponseMessage Command([ValueProvider(typeof(HeaderValueProviderFactory))] string typeName)
{
object reply = null;
var code = HttpStatusCode.OK;
try
{
var cmdObject = DeserializeRequest(typeName);
var method = _commandMethod.MakeGenericMethod(type);
method.Invoke(this, new object[] { request });
}
catch (Exception exception)
{
code = HttpStatusCode.InternalServerError;
reply = exception;
}
var responseMsg = new HttpResponseMessage(code);
if (reply != null)
{
responseMsg.Headers.Add("X-TypeName", reply.GetType().AssemblyQualifiedName);
var replyJson = JsonConvert.SerializeObject(reply);
responseMsg.Content = new StringContent(replyJson, Encoding.UTF8, "application/json");
}
return responseMsg;
}
Run Code Online (Sandbox Code Playgroud)
其中调用以下方法:
private void ExecuteCommand<T>(T command) where T : Command
{
var task = _commandBus.ExecuteAsync(command);
task.Wait(TimeSpan.FromSeconds(10));
}
Run Code Online (Sandbox Code Playgroud)
原因是_commandBus只有一个我需要调用的通用方法。
然而,问题是ExecuteCommand有时似乎会陷入僵局。我不明白为什么。该ICommandBus.ExecuteAsync方法将使用 async/await 调用其他任务,因此它可能是某种死锁,因为 WebApi 使用同步上下文?(等待 vs Task.Wait - 死锁?)
所以如果我理解正确的话,可能有两种解决方案:
MethodInfo?当涉及到这两种解决方案时,我都迷失了。任何人都可以帮忙吗?
更改为ExecuteCommand<T>如下所示(我假设您的实际代码会在超时时执行某些操作):
private async Task ExecuteCommandAsync<T>(T command) where T : Command
{
var timeout = Task.Delay(TimeSpan.FromSeconds(10));
var task = _commandBus.ExecuteAsync(command);
await Task.WhenAny(task, timeout);
}
Run Code Online (Sandbox Code Playgroud)
并进行任何称呼async Task。然后,当您调用该方法时,您可以这样做:
var task = method.Invoke(this, new object[] { request }) as Task;
await task;
Run Code Online (Sandbox Code Playgroud)