c# - .NET Core 2.0 下面的代码线程安全吗
问题描述
这是我的代码,我对线程安全的实现有疑问。我的问题如下
GetHtmlPageAsync 的返回值是对象。它是线程安全的吗?我将使用这个对象并添加到集合中,最后上传到数据库中。
主要方法逻辑如下(正在进行中)。我有一组域,我在集合中有 10000 个域的列表,我的想法是,我将其放入队列中并调用 GetHtmlPageAsync 以获取页面的 HTML。基于 HTML,我将获得必要的超链接。获得超链接后,我将检查链接中是否存在某些单词。如果该词在链接中可用,我将调用相同的方法 GetHTMLPageAsync 来获取该页面的 HTML。所以同一个线程可能会调用 GetHtmlPageAsync 来处理另一个链接。我正在尝试以线程安全的方式对多个调用重用相同的方法。请帮忙。
@edit1。我添加了主要方法。而不是队列。我用过 ForEach
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
解决方案
一般来说,局部变量应该是线程安全的(只是因为他们不知道甚至还有另一个线程并且其他线程无法访问它们)。
应该查看可以被多个线程访问的任何内容。_domainList
例如。确保该Add
方法是线程安全的,因为您可能会并行调用它。
推荐阅读
- javascript - 对一组对象执行一些检查,如果其中一个条件匹配,则停止批量请求
- reactjs - React history.push 自动重定向
- image - 如何应用非最大抑制进行角点检测
- c - 哈希表未在 C 中填充
- android - Android BLE 未显示结果
- node.js - “重新安装 nodejs 后出现错误”
- c++ - C++ 导入关键字、模块关键字和导出关键字
- java - BottomNavigationActivity 中的片段变形
- java - 如何为 java jar 文件创建 Windows 安装程序?
- html - top/bottom:[%] 基于父元素的边框而不是高度