.NET Core 2.0以下代码线程是安全的

时间:2018-05-25 10:11:52

标签: c# .net multithreading thread-safety

这是我的代码,我对线程安全实现有疑问。我的问题在下面

  1. GetHtmlPageAsync的返回值是object。它是线程安全的吗?我将使用此对象并添加到集合中,最后上传到数据库。

  2. 主要方法逻辑如下(实施正在进行中)。我有一组域名,我在集合中有10000个域名列表,我的想法是,我会把它放在队列中并调用GetHtmlPageAsync来获取页面的HTML。基于HTML,我将获得必要的超链接。一旦我获得超链接,我将检查链接中是否有可用的单词。如果链接中有单词,我将调用GetHTMLPageAsync相同的方法来获取该页面的HTML。因此,同一个线程可以调用GetHtmlPageAsync来处理另一个链接。我试图以线程安全的方式重用相同的方法进行多次调用。请帮忙。

  3. @ 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
    

1 个答案:

答案 0 :(得分:0)

一般来说,局部变量应该是线程安全的(仅仅是因为他们根本不知道有另一个线程和其他线程无法访问它们)。

应该查看多个线程可以访问 的任何内容。例如_domainList。确保Add方法是线程安全的,因为您可能并行调用它。