异步和单个实例 class 使用模型

Async and a single instance class working with Models

我正在使用 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 上伪缓存了一些数据。为此,我使用单个实例 class,其中包含我要保留的模型的表示,以便我可以模拟响应和 return 处于离线模式时的响应 ManageOfflineRequests

我的问题是:由于这是一个内部包含 await 的 Async 方法,访问我在单例 class 中由 [=2] 调用的列表是否存在任何潜在问题=] 和 ManageofflineRequests?

谢谢

Since this is a Async method that contains a await inside, is there any potential issues accessing the lists I have inside singleton class called by the ManageOnlineRequests and ManageofflineRequests?

这不是 async-await 特有的。如果您的缓存在单例中并且被 多个线程 同时访问,那么您的缓存将出现竞争条件。您必须通过使用简单的 lock 或使用并发收集来保存您的数据,例如 ConcurrentDictionary.

来确保您正确地保护了您的资产

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

正如 Yuval 所说,这与 async-await 无关。如果您计划同时使用这些列表,则需要确保它们是线程安全的。

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

It is safe to perform multiple read operations on a List, but issues can occur if the collection is modified while it’s being read

来自List Class

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