我喜歡這樣的場景:
我有一個端點,這個端點將把 List 或 Queue 中的請求保存在記憶體中,它會立即向消費者回傳成功回應。這個要求很關鍵,消費者不應該等待回應,如果需要,它會從不同的端點獲得回應。因此,此端點必須在將請求訊息保存在記憶體中后盡快回傳。
另一個執行緒會將這些請求分發到其他端點并將回應保存在記憶體中。
到目前為止我所做的:
我創建了一個控制器 api 來將這些請求保存在記憶體中。我將它們保存在一個靜態請求串列中,如下所示:
public static class RequestList
{
public static event EventHandler<RequestEventArgs> RequestReceived;
private static List<DistributionRequest> Requests { get; set; } = new List<DistributionRequest>();
public static int RequestCount { get => RequestList.Requests.Count; }
public static DistributionRequest Add(DistributionRequest request)
{
request.RequestId = Guid.NewGuid().ToString();
RequestList.Requests.Add(request);
OnRequestReceived(new RequestEventArgs { Request = request });
return request;
}
public static bool Remove(DistributionRequest request) => Requests.Remove(request);
private static void OnRequestReceived(RequestEventArgs e)
{
RequestReceived?.Invoke(null, e);
}
}
public class RequestEventArgs : EventArgs
{
public DistributionRequest Request { get; set; }
}
另一個類訂閱了該靜態類中存在的那個事件,我正在創建一個新執行緒來發出一些后臺 Web 請求,以便能夠實作我上面提到的 2. 專案。
private void RequestList_RequestReceived(object sender, RequestEventArgs e)
{
_logger.LogInformation($"Request Id: {e.Request.RequestId}, New request received");
Task.Factory.StartNew(() => Distribute(e.Request));
_logger.LogInformation($"Request Id: {e.Request.RequestId}, New task created for the new request");
//await Distribute(e.Request);
}
public async Task<bool> Distribute(DistributionRequest request)
{
//Some logic running here to send post request to different endpoints
//and to save results in memory
}
這是我的控制器方法:
[HttpPost]
public IActionResult Post([FromForm] DistributionRequest request)
{
var response = RequestList.Add(request);
return Ok(new DistributionResponse { Succeeded = true, RequestId = response.RequestId });
}
我嘗試了這種方法,但它沒有按我預期的那樣作業,它應該在幾毫秒內回傳,因為我不是在等待回應,但它似乎在等待某些東西,并且在每個請求等待時間增加后,如下所示:

我究竟做錯了什么?或者你有更好的主意嗎?我怎樣才能實作我的目標?
uj5u.com熱心網友回復:
根據您的示例代碼,我嘗試在沒有“事件”的情況下實作它。因此,我得到了更好的請求時間。我不能說這是否與您的實施或事件本身有關,您必須進行分析。
我是這樣做的

請求控制器
就像你在你的例子中那樣。接受請求并將其添加到請求串列中。
[Route("requests")]
public class RequestsController : ControllerBase
{
private readonly RequestManager _mgr;
public RequestsController(RequestManager mgr)
{
_mgr = mgr;
}
[HttpPost]
public IActionResult AddRequest([FromBody] DistributionRequest request)
{
var item = _mgr.Add(request);
return Accepted(new { Succeeded = true, RequestId = item.RequestId });
}
}
請求管理器
管理請求串列并將它們轉發到某個分發服務器。
public class RequestManager
{
private readonly ILogger _logger;
private readonly RequestDistributor _distributor;
public IList<DistributionRequest> Requests { get; } = new List<DistributionRequest>();
public RequestManager(RequestDistributor distributor, ILogger<RequestManager> logger)
{
_distributor = distributor;
_logger = logger;
}
public DistributionRequest Add(DistributionRequest request)
{
_logger.LogInformation($"Request Id: {request.RequestId}, New request received");
/// Just add to the list of requests
Requests.Add(request);
/// Create and start a new task to distribute the request
/// forward it to the distributor.
/// Be sure to not add "await" here
Task.Factory.StartNew(() => _distributor.DistributeAsync(request));
_logger.LogInformation($"Request Id: {request.RequestId}, New task created for the new request");
return request;
}
}
請求分發器
分發邏輯可以在這里實作
public class RequestDistributor
{
public async Task DistributeAsync(DistributionRequest request)
{
/// do your distribution here
/// currently just a mocked time range
await Task.Delay(5);
}
}
接線
...將所有這些內容添加到您的依賴項注入配置中
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSingleton<RequestDistributor>();
services.AddSingleton<RequestManager>();
}
測驗
使用此處提供的代碼片段,我在不到 10 毫秒的時間內收到了所有請求。

筆記
This is just an example try to always add interfaces to your services to make them testable ;).
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/327291.html
