Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# IHttpActionResult.ExecuteAsync()重载返回的任务未运行_C#_Owin_Webapi2_Self Host Webapi - Fatal编程技术网

C# IHttpActionResult.ExecuteAsync()重载返回的任务未运行

C# IHttpActionResult.ExecuteAsync()重载返回的任务未运行,c#,owin,webapi2,self-host-webapi,C#,Owin,Webapi2,Self Host Webapi,我正在尝试创建一个自托管Web服务,该服务通过Microsoft.Owin.Hosting.WebApp.Start(“http://localhost:9000/“并包含从System.Net.Http.ApicController派生的控制器通知启动如下所示: using System.Web.Http; using Owin; ... class NotifyStartup { public void Configuration(IAppBuilder appBuilder)

我正在尝试创建一个自托管Web服务,该服务通过
Microsoft.Owin.Hosting.WebApp.Start(“http://localhost:9000/“
并包含从
System.Net.Http.ApicController
派生的控制器<代码>通知启动如下所示:

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);
    }
}
运行该包装器任务,客户端接收其响应

据我所知,由
newtask…
Task.FromResult()
创建的任务应该与调用者看起来相同。为什么它要等待一个而不是另一个呢?我做错了什么?有可能做到这一点吗

newtask
Task.FromResult()创建的任务应如下所示
与来电者相同

从调用方的角度来看,它们看起来是相同的,但从实现的角度来看,它们是不同的

任务
构造函数不会启动任务,因此不应该使用它。使用
Task.Run
返回热任务:

public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
    return Task.Run(() =>
    {
        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);
}
公共任务执行同步(CancellationToken CancellationToken) { 返回任务。运行(()=> { var rspContent=“这是一个响应字符串”; var rsp=新的HttpResponseMessage(System.Net.HttpStatusCode.OK); 如果(!string.IsNullOrEmpty(rspContent)) { rsp.Content=新的StringContent(rspContent); } 返回rsp; },取消令牌); }
虽然我认为这本身可能是多余的,但由于WebAPI中的操作本身已经在线程池线程上运行,因此将其包装在附加线程中通常是多余的

newtask
Task.FromResult()创建的任务应如下所示
与来电者相同

从调用方的角度来看,它们看起来是相同的,但从实现的角度来看,它们是不同的

任务
构造函数不会启动任务,因此不应该使用它。使用
Task.Run
返回热任务:

public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
    return Task.Run(() =>
    {
        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);
}
公共任务执行同步(CancellationToken CancellationToken) { 返回任务。运行(()=> { var rspContent=“这是一个响应字符串”; var rsp=新的HttpResponseMessage(System.Net.HttpStatusCode.OK); 如果(!string.IsNullOrEmpty(rspContent)) { rsp.Content=新的StringContent(rspContent); } 返回rsp; },取消令牌); }

虽然我认为这本身可能是多余的,但由于WebAPI中的某个操作本身已经在线程池线程上运行,因此通常将其包装在其他线程中是多余的。

有些事情我不知道,有些事情我不知道,还有另一个不喜欢.NET的原因。来自C++的我假设任务在哪里和何时运行,直到运行时,调用它的结果足以保证它将同步运行或异步运行。考虑到我在这里唯一的选择是在线程池中显式地调度它,如果可能的话,我最好确保我进行的所有I/O绑定调用都是异步的,并且放弃创建一个实际的、线程可运行的任务。@EvanBurkitt如果您的操作是IO绑定的,那么您根本不需要使用
task.Run
,您需要查看并利用API本身公开异步端点,例如用于进行异步HTTP调用的
HttpClient
。是的,这就是我的意思。我应该调用
wait
异步函数,而不是创建任务。C#中的异步编程似乎是低级(必须明确决定任务的运行方式和时间)和高级(由
wait
操作符创建的神奇延续)的奇怪混合。我不确定我是否喜欢,但我会习惯的。谢谢你的帮助。有些事情我不知道,还有另一个不喜欢.NET的原因。来自C++的我假设任务在哪里和何时运行,直到运行时,调用它的结果足以保证它将同步运行或异步运行。考虑到我在这里唯一的选择是在线程池中显式地调度它,如果可能的话,我最好确保我进行的所有I/O绑定调用都是异步的,并且放弃创建一个实际的、线程可运行的任务。@EvanBurkitt如果您的操作是IO绑定的,那么您根本不需要使用
task.Run
,您需要查看并利用API本身公开异步端点,例如用于进行异步HTTP调用的
HttpClient
。是的,这就是我的意思。我应该调用
wait
异步函数,而不是创建任务。C#中的异步编程似乎是低级(必须明确决定任务的运行方式和时间)和高级(由
wait
操作符创建的神奇延续)的奇怪混合。我不确定我是否喜欢,但我会习惯的。我感谢你的帮助。