我正在尝试创建一个自托管的 Web 服务,该服务启动它的服务器Microsoft.Owin.Hosting.WebApp.Start<NotifyStartup>("http://localhost:9000/")
并包含一个从System.Net.Http.ApiController
. NotifyStartup
看起来像这样:
using System.Web.Http;
using Owin;
...
class NotifyStartup
{
public void Configuration(IAppBuilder appBuilder)
{
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
appBuilder.UseWebApi(config);
}
}
控制器有这个 URI 处理程序:
using System.Web.Http;
...
[Route("notify")]
[HttpPost]
public IHttpActionResult Notify([FromBody]object body)
{
return new HttpAction();
}
这是HttpAction:
using System.Net.Http;
using System.Web.Http;
using System.Threading;
using System.Threading.Tasks;
...
public class HttpAction : IHttpActionResult
{
public HttpAction() { }
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
return new Task<HttpResponseMessage>(() =>
{
var rspContent = "here's a response string";
var rsp = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
if (!string.IsNullOrEmpty(rspContent))
{
rsp.Content = new StringContent(rspContent);
}
return rsp;
}, cancellationToken);
}
}
(在某些时候HttpAction
会注意Notify()
'sbody
参数,并 rspContent
会分配一些需要一些数据库查找的东西,这就是为什么我试图使这项工作异步进行。)
当我运行程序并 POST 到http://localhost:9000/notify/时,会调用 URI 处理程序,它会创建一个HttpAction
实例并ExecuteAsync()
调用该实例的方法。但是,它返回的任务永远不会运行,客户端挂起等待响应。如果我更改ExecuteAsync()
以便同步完成工作并在包装器任务中返回响应:
var rspContent = "here's a response string";
var rsp = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
if (!string.IsNullOrEmpty(rspContent))
{
rsp.Content = new StringContent(rspContent);
}
return Task.FromResult(rsp);
该包装器任务运行并且客户端收到它的响应。
据我所知,由调用者创建的任务看起来应该new Task<>...
与Task.FromResult()
调用者相同。为什么它await
(或它实际为获得结果所做的任何事情)是一个而不是另一个?我究竟做错了什么?有可能完成这项工作吗?