C# 如何使用Async实现这一点?

C# 如何使用Async实现这一点?,c#,asynchronous,C#,Asynchronous,我有两个正在运行的服务,a和B(都是web api)以及一个http客户端。这是我希望异步完成的事件序列: 客户端调用并传递对象O作为参数 一个异步进程(P1)开始处理O P1运行时,A向B[P2](可能需要一段时间)发送异步消息,以便B对其进行处理。实际上,A现在是B的客户机 [这是重要的部分] P1完成工作后,我希望A将OK响应发送回调用客户端 我不想让客户机等到B向A发送自己的响应后,A才能用OK响应客户机 就客户机而言,A只做P1,也就是说,不关心A和B之间的通信,它只关心P1的结果 A

我有两个正在运行的服务,a和B(都是web api)以及一个http客户端。这是我希望异步完成的事件序列:

  • 客户端调用并传递对象O作为参数
  • 一个异步进程(P1)开始处理O
  • P1运行时,A向B[P2](可能需要一段时间)发送异步消息,以便B对其进行处理。实际上,A现在是B的客户机
  • [这是重要的部分]

  • P1完成工作后,我希望A将OK响应发送回调用客户端
  • 我不想让客户机等到B向A发送自己的响应后,A才能用OK响应客户机
  • 就客户机而言,A只做P1,也就是说,不关心A和B之间的通信,它只关心P1的结果
  • A应该以自己的速度处理B在自己的时间内可能发送的任何响应
  • P1和P2都是异步方法,我已经定义并使用了它们
  • 6-9仅用于澄清目的,但我如何完成5

    我与MS stack合作,VS2013,C#5

    下面是我试图实现的伪代码:

     // this is the clinent and where it all begins
    class Class1
    {
        static void Main()
        {
            using (var client = new HttpClient())
            {
                var o = new SomeObject();
                var response = client.PostAsJsonAsync(api, o);
                Console.Write(response.Status);
            }
        }
    }
    
    // this one gets called from the client above
    class ServiceA
    {
        public async Task<IHttpActionResult> Post([FormBody] SomeObject someObject)
        {
            // this one I want to wait for
            var processed = await ProcessSomeObjectA(SomeObject some);
    
            // now, how do I call SendToService so that this POST
            // will not wait for completion
            SendToService(someObject);
    
            return processed.Result;
    
        }
    
        private async Task<bool> ProcessSomeObjectA(SomeObject some)
        {
            // whatever it does it returns Task<bool>
            return true;
        }
    
        private async Task<IHttpActionResult> SendToService(SomeObject someObject)
        {
            using (var client = new HttpClient())
            {
                var o = new SomeObject();
                var response = await client.PostAsJsonAsync(api, o);
                return response.StatusCode == HttpStatusCode.OK;
            }
        }
    
    }
    
    class ServiceB
    {
        // this gets called from ServiceA
        public async Task<IHttpActionResult> Post([FormBody] SomeObject someObject)
        {
            return (await ProcessSomeObjectB(someObject))) ? Ok() : BadResponse();
        }
    
        private async Task<bool> ProcessSomeObjectB(SomeObject some)
        {
            // whatever it does it returns Task<bool>
            return true;
        }
    }
    
    //这就是客户,也是一切开始的地方
    一班
    {
    静态void Main()
    {
    使用(var client=new HttpClient())
    {
    var o=新的SomeObject();
    var response=client.PostAsJsonAsync(api,o);
    控制台写入(响应状态);
    }
    }
    }
    //这一个从上面的客户端调用
    A类服务
    {
    公共异步任务发布([FormBody]SomeObject SomeObject)
    {
    //这是我想等的
    var processed=wait ProcessSomeObjectA(SomeObject some);
    //现在,我如何调用SendToService以便
    //不会等待完成
    SendToService(someObject);
    返回处理结果;
    }
    专用异步任务进程SomeObjectA(SomeObjectSome)
    {
    //无论它做什么,它都返回任务
    返回true;
    }
    专用异步任务SendToService(SomeObject SomeObject)
    {
    使用(var client=new HttpClient())
    {
    var o=新的SomeObject();
    var response=wait client.PostAsJsonAsync(api,o);
    返回response.StatusCode==HttpStatusCode.OK;
    }
    }
    }
    B类服务
    {
    //这将从ServiceA调用
    公共异步任务发布([FormBody]SomeObject SomeObject)
    {
    return(wait ProcessSomeObjectB(someObject))?Ok():BadResponse();
    }
    专用异步任务ProcessSomeObjectB(SomeObjectSome)
    {
    //无论它做什么,它都返回任务
    返回true;
    }
    }
    
    没有您拥有的示例。我想你是在找一份工作

    您希望在不“等待”的情况下启动对B的调用,这样您就可以关闭P1任务并返回,然后您可能需要这样的内容

    请也看看这里:


    我希望这有帮助

    没有你的例子。我想你是在找一份工作

    您希望在不“等待”的情况下启动对B的调用,这样您就可以关闭P1任务并返回,然后您可能需要这样的内容

    请也看看这里:


    我希望这有帮助

    我猜您想要的是以“点燃并忘记”的方式调用B方法:


    我猜您想要的是以“fire-and-forget”的方式调用B方法:


    在服务“A”中尝试以下代码:

    public异步任务ServiceAAction()
    {
    尝试
    {
    var client=新的HttpClient();
    client.GetAsync(“http://URLtoWebApi/ServiceB)继续(HandlerResponse);
    //这里的任何代码都将立即执行,因为上面的行没有等待
    //向客户端返回指示服务A“完成”的响应
    返回Request.CreateResponse(HttpStatusCode.OK);
    }
    抓住
    {
    抛出新的HttpResponseException(HttpStatusCode.InternalServerError);
    }
    }
    专用异步void HandleResponse(任务响应)
    {
    尝试
    {
    //等待服务B的响应
    var结果=等待响应;
    //工作
    //不要尝试返回任何内容,服务A已向客户端返回响应
    }
    捕获(例外e)
    {
    投掷;
    }
    }
    

    我已经玩过一点了。我的测试客户机(使用“A”)立即收到响应消息。方法HandleResponse()在第二个api(“B”)完成其工作后被命中。此安装程序无法将第二条消息返回到“a”的客户端,我相信您正在寻找此消息。

    请在服务“a”中尝试以下代码:

    public异步任务ServiceAAction()
    {
    尝试
    {
    var client=新的HttpClient();
    client.GetAsync(“http://URLtoWebApi/ServiceB)继续(HandlerResponse);
    //这里的任何代码都将立即执行,因为上面的行没有等待
    //向客户端返回指示服务A“完成”的响应
    返回Request.CreateResponse(HttpStatusCode.OK);
    }
    抓住
    {
    抛出新的HttpResponseException(HttpStatusCode.InternalServerError);
    }
    }
    专用异步void HandleResponse(任务响应)
    {
    尝试
    {
    //等待服务B的响应
    var结果=等待响应;
    //工作
    //不要尝试返回任何内容,服务A已向客户端返回响应
    }
    捕获(例外e)
    {
    投掷;
    }
    }
    

    我已经玩过一点了。我的测试客户机(使用“A”)立即收到响应消息。方法HandleResponse()在第二个api(“B”)完成其工作后被命中。此设置无法将第二条消息返回给“a”的客户端,我相信您正在寻找此消息。

    您能提供一些示例代码吗?它会像s一样容易吗
        public Task TaskA(object o)
        {
            //Do stuff
    
            //Fire and Forget: call Task B, 
            //create a new task, dont await 
            //but forget about it by moving to the next statement
            TaskB(); 
    
            //return;
        }
        public  Task TaskB()
        {
            //...
        }
    
        public async Task Client()
        {
            var obj = "data";
    
            //this will await only for TaskA
            await TaskA(obj);
        }
    
    public async Task<HttpResponseMessage> ServiceAAction()
    {
        try
        {
            var client = new HttpClient();
            client.GetAsync("http://URLtoWebApi/ServiceB").ContinueWith(HandleResponse);
    
            // any code here will execute immediately because the above line is not awaited
    
            // return response to the client indicating service A is 'done'
            return Request.CreateResponse(HttpStatusCode.OK);
    
        }
        catch
        {
            throw new HttpResponseException(HttpStatusCode.InternalServerError);
        }
    }
    
    private async void HandleResponse(Task<HttpResponseMessage> response)
    {
        try
        {
            // await the response from service B
            var result = await response;
    
            // do work
    
            // dont attempt to return anything, service A has already returned a response to the client
        }
        catch (Exception e)
        {
            throw;
        }
    }