如何使用Async完成此操作
本文关键字:操作 何使用 Async | 更新日期: 2023-09-27 18:25:17
我运行了两个服务,a和B(都是web api)和一个http客户端。这是我想要异步完成的一系列事件:
- 客户端调用A并传递对象O作为参数
- A开始异步进程(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堆栈、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;
}
}
在服务"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#中使用不带等待的异步吗?
我希望这能有所帮助。