C# .NET Core 2.0是以下代码的线程安全版本
这是我的代码,我对线程安全实现有疑问。我的问题如下C# .NET Core 2.0是以下代码的线程安全版本,c#,.net,multithreading,thread-safety,C#,.net,Multithreading,Thread Safety,这是我的代码,我对线程安全实现有疑问。我的问题如下 GetHtmlPageAsync的返回值为object。它是线程安全的吗?我将使用这个对象并添加到集合中,最后上传到数据库中 主要方法逻辑如下(正在实施)。我有一组域,集合中有10000个域的列表,我的想法是,我将把它放在队列中,并调用GetHtmlPageAsync来获取页面的HTML。基于HTML,我将获得必要的超链接。一旦我得到超链接,我会检查链接中的某些单词是否可用。如果这个词在链接中可用,我将调用相同的方法GetHTMLPageAsy
public static async Task<int> ProcessDomainAsync(List<string> domains)
{
Parallel.ForEach(domains, async (currentDomain) =>
{
var domainBody = await GetHtmlPageAsync(currentDomain);
var language = string.Empty;
var country = string.Empty;
var createdOn = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
var updatedOn = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
var machine = Environment.MachineName;
var message = "[" + domainBody.ErrorCode + "] - " + domainBody.ErrorMessage;
var active = false;
var stage = "End";
var url = currentDomain;
if (domainBody.ErrorCode == 0)
{
var html = domainBody.Body;
language = Common.GetLanguageIdentification(html);
country = Common.GetCountryIdentification(currentDomain);
message = string.Empty;
active = true;
stage = "Stage1";
var hyperLinks = Common.GetAllAHrefTags(html);
//Process Hyper Links
}
_domainList.Add(new Domain
{
Url = url,
Language = language,
Country = country,
MachineName = machine,
Message = message,
Active = active,
Stage = stage,
CreatedOn = createdOn,
UpdatedOn = updatedOn
});
domainCount++;
});
return domainCount;
}
public class DomainBody
{
public string Body;
public string ErrorMessage;
public int ErrorCode;
}
public static class DomainProcessing {
static async Task<DomainBody> GetHtmlPageAsync(string url)
{
#region Initialize Proxy
var sessionId = new Random().Next().ToString();
var proxy = new WebProxy(Constant.ProxyUrl, Constant.ProxyPort);
var login = Constant.ProxyUserName + "-session-" + sessionId;
proxy.Credentials = new NetworkCredential(login,Constant.ProxyPassword);
#endregion
#region Initialize Variables
var user_agent = Common.GenerateRandomUserAgent();
var body = string.Empty;
var errorCode = 0;
var errorMessage = string.Empty;
#endregion
try
{
#region Format URL with Http Protocol
var domainSB = new StringBuilder();
domainSB.Append("http://");
domainSB.Append(url);
#endregion
#region Process Domain
var request = (HttpWebRequest) WebRequest.Create(new Uri(url));
request.Proxy = proxy;
request.UserAgent = user_agent;
request.Timeout = Constant.TimeOut;
using (var response = await request.GetResponseAsync().ConfigureAwait(true))
using (var content = new MemoryStream())
using (var responseStream = response.GetResponseStream())
{
await responseStream.CopyToAsync(content);
var bodyArray = content.ToArray();
body = Encoding.UTF8.GetString(bodyArray, 0, bodyArray.Length);
}
errorCode = 0;
errorMessage = string.Empty;
#endregion
}
catch (HttpRequestException ex)
{
body = string.Empty;
errorCode = ex.InnerException.HResult;
errorMessage = ex.InnerException.Message;
}
catch (Exception ex)
{
body = string.Empty;
errorCode = ex.HResult;
errorMessage = ex.Message;
}
var domainBody = new DomainBody
{
Body = body,
ErrorCode = errorCode,
ErrorMessage = errorMessage
};
return domainBody;
}
}enter code here
公共静态异步任务ProcessDomainAsync(列出域)
{
Parallel.ForEach(域,异步(currentDomain)=>
{
var domainBody=等待GetHtmlPageAsync(currentDomain);
var language=string.Empty;
var country=string.Empty;
var createdOn=DateTime.SpecifyKind(DateTime.Now,DateTimeKind.Local);
var updatedOn=DateTime.SpecifyKind(DateTime.Now,DateTimeKind.Local);
var machine=Environment.MachineName;
var message=“[”+domainBody.ErrorCode+”]-“+domainBody.ErrorMessage;
var-active=false;
var stage=“结束”;
var url=currentDomain;
if(domainBody.ErrorCode==0)
{
var html=domainBody.Body;
language=Common.GetLanguageIdentification(html);
country=Common.GetCountryIdentification(currentDomain);
message=string.Empty;
主动=真;
stage=“Stage1”;
var hyperLinks=Common.GetAllAHrefTags(html);
//处理超链接
}
_domainList.Add(新域)
{
Url=Url,
语言=语言,
国家,
MachineName=机器,
消息=消息,
活动=活动,
舞台,
CreatedOn=CreatedOn,
UpdatedOn=UpdatedOn
});
domainCount++;
});
返回域计数;
}
公共类域主体
{
公共机构;
公共字符串错误消息;
公共内部错误代码;
}
公共静态类域处理{
静态异步任务GetHtmlPageAsync(字符串url)
{
#区域初始化代理
var sessionId=new Random().Next().ToString();
var proxy=新的WebProxy(Constant.ProxyUrl、Constant.ProxyPort);
var login=Constant.ProxyUserName+“-session-”+sessionId;
proxy.Credentials=新的网络凭据(登录名,常量.ProxyPassword);
#端区
#区域初始化变量
var user_agent=Common.GenerateRandomUserAgent();
var body=string.Empty;
var errorCode=0;
var errorMessage=string.Empty;
#端区
尝试
{
#使用Http协议的区域格式URL
var domainSB=新的StringBuilder();
domainSB.Append(“http://”);
域名b.Append(url);
#端区
#区域过程域
var request=(HttpWebRequest)WebRequest.Create(新Uri(url));
request.Proxy=Proxy;
request.UserAgent=user\u agent;
request.Timeout=Constant.Timeout;
使用(var response=await request.GetResponseAsync().ConfigureAwait(true))
使用(var content=new MemoryStream())
使用(var responseStream=response.GetResponseStream())
{
等待响应ream.CopyToAsync(内容);
var bodyArray=content.ToArray();
body=Encoding.UTF8.GetString(bodyArray,0,bodyArray.Length);
}
错误代码=0;
errorMessage=string.Empty;
#端区
}
捕获(HttpRequestException-ex)
{
body=string.Empty;
errorCode=ex.InnerException.HResult;
errorMessage=ex.InnerException.Message;
}
捕获(例外情况除外)
{
body=string.Empty;
errorCode=ex.HResult;
errorMessage=ex.Message;
}
var domainBody=新的domainBody
{
身体,
ErrorCode=错误代码,
ErrorMessage=ErrorMessage
};
返回域体;
}
}在这里输入代码
一般来说,局部变量应该是线程安全的(只是因为它们不知道还有另一个线程,而其他线程也无法访问它们)
任何可以被多个线程访问的东西都应该考虑<代码>\u域列表例如。确保
Add
方法是线程安全的,因为您可能会并行调用它。问问题的方式是否有问题。不确定。为什么会被否决,而被否决的选民没有给出任何具体原因。这是我在stackoverflow中的第四个或第五个问题。不是每个人都能在一天之内成为大师。只是我的想法,没有冒犯。谢谢你的快速回复。我正在使用BlockingCollection。我认为BlockingCollection添加和获取是线程安全的。我是否需要添加锁,然后将对象添加到BlockingCollection。BlockingCollection应该可以。