如何使用Async完成此操作

本文关键字:操作 何使用 Async | 更新日期: 2023-09-27 18:25:17

我运行了两个服务,a和B(都是web api)和一个http客户端。这是我想要异步完成的一系列事件:

  1. 客户端调用A并传递对象O作为参数
  2. A开始异步进程(P1),用O做一些事情
  3. 当P1运行时,A向B[P2]发送异步消息(可能需要一段时间),让B对其进行处理。本质上,A现在是B的客户端

[这是重要的部分]

  1. 一旦P1完成其工作,我希望A将OK响应发送回呼叫客户端
  2. 我不想让客户端等到B向A发送自己的响应后,A才能用OK响应客户端
  3. 就客户端而言,A只做P1,仅此而已,不关心A和B之间的通信,只关心P1的结果
  4. A应该按照自己的节奏处理B在自己的时间发送的任何响应
  5. P1和P2都是异步方法,我已经定义并正在使用

6-9只是为了澄清,但我如何完成5?

我正在使用MS堆栈、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;
    }
}

如何使用Async完成此操作

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

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;
    }
}

我已经玩过一点了。我的测试客户端(使用"A")立即收到一条响应消息。方法HandleResponse()在第二个api("B")完成其工作后被命中。这个设置无法将第二条消息返回到"a"的客户端,我相信你无论如何都在追求这一点。

我想你想要的是以"fire-and-forget"的方式调用B方法:

    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);
    }

没有您所拥有的示例。我想您正在寻找一个带回调的异步。

你想在不"等待"的情况下开始对B的呼叫,这样你就可以关闭你的P1任务并返回,然后你就会想要这样的东西。

也请看一下这里:我可以在c#中使用不带等待的异步吗?

我希望这能有所帮助。