异步和与模型一起使用的单个实例类

本文关键字:单个 实例 模型 一起 异步 | 更新日期: 2023-09-27 18:36:41

我正在使用WebApi委派处理程序将请求转发到另一台服务器。

protected override async System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
    string requestContent = string.Empty;
    UriBuilder forwardUri = new UriBuilder(request.RequestUri);
    //remove the proxy port and replace with an Http port
    forwardUri.Port = 1900;
    //send it on to the requested URL
    request.RequestUri = forwardUri.Uri;
    HttpClient client = new HttpClient();
    if (request.Method == HttpMethod.Get)
    {
        request.Content = null;
    }
    try
    {
        var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
        if (response.IsSuccessStatusCode)
        {
            ManageOnlineRequests(response);
        }
        return response;
    }
    catch (Exception ex)
    {
        return ManageOfflineRequests(request);
    }
}

一切正常,但我正在伪缓存ManageOnlineRequests上的一些数据.为此,我使用了一个实例类,其中包含我要保留的模型的表示形式,以便我可以模拟响应并在离线模式下返回响应 ManageOfflineRequests .

我的问题是:由于这是一个内部包含await的异步方法,因此访问我在 ManageOnlineRequestsManageofflineRequests 调用的单例类中的列表是否存在任何潜在问题?

谢谢

异步和与模型一起使用的单个实例类

正如尤瓦尔所说,这与async-await无关。如果计划并发使用这些列表,则需要确保它们是线程安全的。

现在,最简单的选择是使用 lock ,但是如果您专门使用List<T>,只要您只从中读取而不是同时更新它,它就可以保证是线程安全的:

对一个列表执行多个读取操作是安全的,但如果在读取集合时修改集合,则可能会出现问题

从列表类

更好的解决方案是使用 ImmutableList<T> out of Microsoft.Bcl.Immutable,因为它是不可变的,因此保证是线程安全的。

由于这是一个内部包含 await 的异步方法,因此是否有 访问我在单例类中的列表的任何潜在问题 由 ManageOnlineRequests 和 ManageofflineRequests?

这不是特定于async-await的。如果您的缓存位于单一实例中,并且由多个线程并发访问,则会出现对缓存的争用条件。您必须确保通过使用简单的lock或使用并发收集来保存数据(例如ConcurrentDictionary)来正确保护您的资产。

async-await本身不会生成任何额外的线程,除非您明确告诉它(使用 Task.RunTask.Factory.StartNew )。 await client.SendAsync只会将控制权交给调用线程,直到您的 IO 工作(在本例中为 HTTP 请求)完成,然后通过 IOCP 调用延续。