等待委托中调用的任务

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 - 死锁?

所以如果我理解正确的话,可能有两种解决方案:

  1. 一直使用异步/等待。但是在使用 调用方法时我该怎么做MethodInfo
  2. 更改以便我的调用与同步上下文一起使用

当涉及到这两种解决方案时,我都迷失了。任何人都可以帮忙吗?

Ste*_*ary 5

更改为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)

  • `Task&lt;T&gt;` 继承自 `Task`,所以如果你只想 `await` 它,你不需要做任何其他事情。如果您需要以某种方式返回结果,我建议使用 `dynamic`。 (2认同)