c# - 如何让 API 调用等到之前的调用完成
问题描述
我在 c# (MYAPI) 中有一个 API,它接受一个请求,并对 Unity (UNITYAPI) 进行 API 调用以执行某些操作。
流程应该是这样的
客户端 -> MYAPI -> UnityAPI -> 执行任务 -> 从 UnityAPI 到 MYAPI 的响应 -> 对客户端的响应。
现在,客户端可以通过不同的线程调用MYAPI。MYAPI 应该等待前面的 MYAPI 调用完成(这反过来意味着 UNITYAPI 完成了一些操作)。MYAPI "CANNOT" 向 UNITYAPI 发送任何请求,直到之前的 MYAPI 调用响应回客户端。
MYAPI 中用于对 UNITY API 进行 api 调用的函数:
static async Task<string> PostURI(HttpContent c)
{
Uri uri = new Uri("http://localhost:4444");
var response = string.Empty;
using (var client = new HttpClient())
{
HttpResponseMessage result = null;
try
{
result = await client.PostAsync(uri, c);
}
catch (Exception ex)
{
throw ex;
}
if (result.IsSuccessStatusCode)
{
response = result.StatusCode.ToString();
}
}
return response;
}
MYAPI 中处理所有调用的函数:
public void ProcessCalls(string operation)
{
HttpContent next = new StringContent(operation);
while (isBlocked == true)
{
}
isBlocked = true;
var t = Task.Run(() => PostURI(next));
t.Wait();
isBlocked = false;
}
在这里,您可以看到我所做的解决方法。我只是使用了一个静态变量 isBlocked 让任何调用在无限循环中等待,直到完成任何其他操作。
当我向 MYAPI 发送 2 个并行调用时,这工作正常。第二个调用等待第一个调用完成,然后继续向 UNITYAPI 发送调用并等待。但是当我并行发送 3 个调用时,它会中断。第一个呼叫统一完成,但没有收到任何呼叫的响应。必须有一种优雅的方式来做到这一点。
所以我想要的是:-客户端应该能够向 MYAPI 发送多个请求。- 每个请求都应该等到所有先前的请求都将响应发送回客户端。
提前致谢。
编辑 1:调用 ProcessCalls 的方法:
[HttpPost]
[Route("MyPostRoute")]
public async void MyPostRoute()
{
var request = new StreamReader(Request.Body).ReadToEnd();
// Doing some validations on the request
if (request.isValid())
{
await helperobject.ProcessCalls(request);
//helperobject is an object of the class which has the two functions mentioned above.
}
else
throw new Exception("Input was not in Correct format");
}
解决方案
使用 Semaphore,您需要将其设为静态,因此该类的所有实例都使用相同的实例。然后你可以这样:
private static SemaphoreSlim processCallsSemaphore = new SemaphoreSlim(1,1);
// new SemaphoreSlim(1,1); => start with 1 count available and allow at max 1.
public async Task ProcessCalls(string operation)
{
HttpContent next = new StringContent(operation);
try
{
await processCallsSemaphore.WaitAsync();
await PostURI(next); // Assuming this is also an async API or can be made one.
}
finally
{
processCallsSemaphore.Release();
}
}
推荐阅读
- sorting - Google 表格可排序箭头
- android - Android - 删除所有应用程序,设置和自定义应用程序除外
- sql - 简化 sql 查询(日期到期间)
- javascript - 关于JS中闭包的内存效率
- git - GIT sourcetree - 我们需要创建本地分支来拉新的远程分支吗?
- promise - Promise.race() 可能不适合获得最快的答案?
- snowflake-cloud-data-platform - 在雪花中设置系统范围的变量
- visual-studio-mac - Visual Studio Mac 导航到符号不起作用
- javascript - 如何在 node.js 中导入模块或外部 .js 文件
- java - 如何将一个类的值设置为另一个类?