.NET Core 2.0 Является ли приведенный ниже код безопасным - PullRequest
0 голосов
/ 25 мая 2018

Вот мой код, и у меня есть сомнения по поводу потоковой реализации.Мои вопросы ниже

  1. Возвращаемое значение из GetHtmlPageAsync является объектом.Это потокобезопасно?Я буду использовать этот объект и добавить в коллекцию и, наконец, загрузить в базу данных.

  2. Основная логика метода приведена ниже (в процессе реализации).У меня есть набор доменов, у меня есть список из 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

1 Ответ

0 голосов
/ 25 мая 2018

Вообще говоря, локальные переменные должны быть потокобезопасными (просто потому, что они понятия не имеют, что существует даже другой поток, а другие потоки не имеют доступа к ним).

Все, что может быть доступно для нескольких потоков, должно быть просмотрено._domainList например.Убедитесь, что метод Add является потокобезопасным, поскольку вы вызываете его потенциально параллельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...