异步和与模型一起使用的单个实例类
本文关键字:单个 实例 模型 一起 异步 | 更新日期: 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
的异步方法,因此访问我在 ManageOnlineRequests
和 ManageofflineRequests
调用的单例类中的列表是否存在任何潜在问题?
谢谢
正如尤瓦尔所说,这与async-await
无关。如果计划并发使用这些列表,则需要确保它们是线程安全的。
现在,最简单的选择是使用 lock
,但是如果您专门使用List<T>
,只要您只从中读取而不是同时更新它,它就可以保证是线程安全的:
对一个列表执行多个读取操作是安全的,但如果在读取集合时修改集合,则可能会出现问题
从列表类
更好的解决方案是使用 ImmutableList<T>
out of Microsoft.Bcl.Immutable
,因为它是不可变的,因此保证是线程安全的。
由于这是一个内部包含 await 的异步方法,因此是否有 访问我在单例类中的列表的任何潜在问题 由 ManageOnlineRequests 和 ManageofflineRequests?
这不是特定于async-await
的。如果您的缓存位于单一实例中,并且由多个线程并发访问,则会出现对缓存的争用条件。您必须确保通过使用简单的lock
或使用并发收集来保存数据(例如ConcurrentDictionary
)来正确保护您的资产。
async-await
本身不会生成任何额外的线程,除非您明确告诉它(使用 Task.Run
或 Task.Factory.StartNew
)。 await client.SendAsync
只会将控制权交给调用线程,直到您的 IO 工作(在本例中为 HTTP 请求)完成,然后通过 IOCP 调用延续。