C# Async和一个使用模型的单实例类
我正在使用WebApi委托处理程序将请求转发到另一台服务器C# Async和一个使用模型的单实例类,c#,.net,asynchronous,asp.net-web-api,async-await,C#,.net,Asynchronous,Asp.net Web Api,Async Await,我正在使用WebApi委托处理程序将请求转发到另一台服务器 protected override async System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { string requestContent = string.Empty;
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);
}
}
受保护的覆盖异步System.Threading.Tasks.Task SendAsync(HttpRequestMessage请求,System.Threading.CancellationToken CancellationToken)
{
string requestContent=string.Empty;
UriBuilder forwardUri=新的UriBuilder(request.RequestUri);
//删除代理端口并替换为Http端口
forwardUri.Port=1900;
//将其发送到请求的URL
request.RequestUri=forwardUri.Uri;
HttpClient=新的HttpClient();
if(request.Method==HttpMethod.Get)
{
request.Content=null;
}
尝试
{
var response=wait client.sendaync(请求,HttpCompletionOption.ResponseHeadersRead);
if(响应。IsSuccessStatusCode)
{
ManageOnlinerRequests(响应);
}
返回响应;
}
捕获(例外情况除外)
{
返回ManageOfflineRequests(请求);
}
}
一切正常,但我正在ManageOnlineRequests
上伪缓存一些数据。为此,我使用了一个实例类,该类包含我想要保留的模型的表示形式,以便在脱机模式下模拟响应并返回这些响应ManageOfflineRequests
我的问题是:由于这是一个异步方法,内部包含一个await
,访问由ManageOnlineRequests
和ManageofflineRequests
调用的单例类中的列表是否存在任何潜在问题
谢谢
因为这是一个异步方法,其中包含一个wait,所以是否存在
访问singleton类中的列表时有任何潜在问题吗
由ManageOnlineRequests和ManageofflineRequests调用
这不是特定于async wait
的。如果您的缓存位于一个单实例中,并且被多个线程并发访问,那么将存在针对您的缓存的争用条件。您必须通过使用简单的锁
或使用并发收集来保存数据(如ConcurrentDictionary
),确保正确保护您的资产
async wait
本身不会生成任何额外线程,除非您明确告诉它(使用Task.Run
或Task.Factory.StartNew
)<代码>等待客户端。SendAsync将简单地将控制权交给调用线程,直到IO工作(在本例中为HTTP请求)完成,然后通过IOCP调用延续。正如Yuval所说,这与异步等待
无关。如果计划同时使用这些列表,则需要确保它们是线程安全的
现在,最简单的选择是使用锁
,但是如果您特别使用列表
,只要您只从中读取而不同时更新,它就保证是线程安全的:
对一个列表执行多个读取操作是安全的,但如果在读取集合时对其进行修改,则可能会出现问题
从
更好的解决方案是使用Microsoft.Bcl.Immutable中的
ImmutableList
,它保证线程安全,因为它是不可变的。您所说的问题是什么意思?“你是说比赛条件吗?”尤瓦利扎科夫说得对,我不清楚。SendAsync不在我的singleton类中。SendAsync方法调用使用我的资产的单例类方法。我的答案保持不变。如果同时调用SendAsync
,您仍需要同步这些请求。