Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET Core 2.0是以下代码的线程安全版本_C#_.net_Multithreading_Thread Safety - Fatal编程技术网

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

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

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

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

  • @edit1。我添加了main方法。而不是排队。我用过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
    
    公共静态异步任务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应该可以。