如何使用Async完成此操作?

时间:2015-12-01 17:45:57

标签: c# asynchronous

我有几个服务正在运行,A和B(都是web api)和一个http客户端。这是我想要异步完成的事件序列:

  1. 客户端调用A并将对象O作为参数
  2. 传递
  3. A开始异步处理(P1)以使用O,
  4. 执行某些操作
  5. 当P1正在运行时,A向B [P2]发送异步消息(可能需要一段时间),以便B对其执行某些操作。基本上A现在是B
  6. 的客户

    [这是重要的部分]

    1. P1完成工作后,我希望A将OK响应发送回主叫客户端,
    2. 我不想让客户端等到B将自己的响应发送给A之前A可以用OK回复客户端,
    3. 就客户而言A只做P1和它,不关心A和B之间的沟通,它只关心P1的结果
    4. A应该按照自己的节奏处理B可能按照自己的时间发送的任何响应
    5. P1和P2都是异步方法,我已经定义并正在使用
    6. 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;
          }
      }
      

3 个答案:

答案 0 :(得分:1)

在服务“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”)立即收到响应消息。在第二个api(“B”)完成其工作后,方法HandleResponse()被命中。此设置无法将第二条消息返回给“A”的客户端,这是我相信你无论如何都是。

答案 1 :(得分:0)

我猜你想要的是在B&B中调用B方法,然后忘记&#34;方式:

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

答案 2 :(得分:-1)

没有你所拥有的例子。我想你正在寻找一个Async with callback.

你想要在没有“等待”它的情况下开始调用B,这样你就可以关闭你的P1任务并返回然后你想要这样的东西。

请在这里查看:Can i use async without await in c#?

我希望有所帮助。