Помогите получить переменную в новом потоке
являюсь новичком в C#. Вынужденно приходится редактировать программу, без достаточный знаний о работе асинхронна. В программе недоработка, что получение значения прокси для браузера делается внутри потока, из-за чего при сильной загруженности поток может дважды использовать одно и тоже прокси. Я пытаюсь вывести действия с парсингом(получением нового прокси) ( private void Request(object obj) ) в поток с 1-м примером кода, чтобы прокси были разные в Request. Я выложил код без своих тщетных попыток, упирался в то, что не получается передать переменную Proxy в поток Request, ошибка Аргумент 1: не удается преобразовать из "группа методов" в "ParameterizedThreadStart
Возможно, я неправильно вижу проблему
Буду благодарен за любую помощь!
Места о которых идет речь
try
{
_file = new StreamReader(proxyListDirectory);
string line;
while (CanRun && (line = _file.ReadLine()) != null)
{
Thread.Sleep(1000);
line = line.Replace(" ", "");
if (string.IsNullOrEmpty(line))
continue;
var array = line.ToString().Split(':');
string text = File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "\\zipDirectory\\backgroundTemplate.js");
text = text.Replace("{ip}", array[0]).Replace("{port}", array[1]).Replace("{username}", array[2]).Replace("{password}", array[3]);
File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "\\zipDirectory\\background.js", text);
ZipFile.CreateFromDirectory(AppDomain.CurrentDomain.BaseDirectory + "\\zipDirectory", AppDomain.CurrentDomain.BaseDirectory + "\\zipSource\\background" + i + ".zip");
Thread thr = new Thread(Request) { Priority = ThreadPriority.Normal };
Random r = new Random();
int rInt = r.Next(3000, 6000);
while (BrowserLimit > 0 && DriverServices.Count >= BrowserLimit)
{
Thread.Sleep(1000);
}
if (!CanRun)
continue;
loginInfos.TryDequeue(out var loginInfo);
i++;
thr.Start(new SessionConfigurationDto { Url = line, Count = i, PreferredQuality = preferredQuality, LoginInfo = loginInfo});
Thread.Sleep(BrowserLimit == 0 ? rInt : 1000);
}
_file.Close();
}
Это то что вызывается и то что я хочу перенести в первый пример кода, чтобы не было повторений
private void Request(object obj)
{
try
{
Random r = new Random();
SessionConfigurationDto itm = (SessionConfigurationDto)obj;
var array = itm.Url.Split(':');
var driverService = ChromeDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
Proxy proxy = new Proxy
{
Kind = ProxyKind.Manual
};
string proxyUrl = array[0] + ":" + array[1];
string proxyUrl2 = "https://google.com/" + array[4];
proxy.SslProxy = proxyUrl;
proxy.HttpProxy = proxyUrl;
StreamUrl = proxyUrl2;
var chromeOptions = new ChromeOptions { Proxy = proxy, AcceptInsecureCertificates = true };
Весь код( на всякий случай)
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Interactions;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading;
using BotCore.Dto;
using Newtonsoft.Json;
namespace BotCore
{
public class Core
{
public static string ZipDirectory = string.Empty;
public static string StreamUrl = string.Empty;
public static bool Headless;
public static int BrowserLimit;
public string PreferredQuality;
private int _refreshInterval;
public bool CanRun = true;
private bool _error;
private bool _firstPage = true;
private static readonly ConcurrentQueue<ChromeDriverService> DriverServices = new ConcurrentQueue<ChromeDriverService>();
private StreamReader _file;
public Action AllBrowsersTerminated;
public Action<string> InitializationError;
public Action<string> LogMessage;
public Action DidItsJob;
public Action IncreaseViewer;
public Action DecreaseViewer;
public Action<string> LiveViewer;
private readonly object _lockObject = new object ();
private readonly string _loginCookiesPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data", "loginCookies.json");
readonly JsonSerializerSettings _isoDateFormatSettings = new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
DateParseHandling = DateParseHandling.DateTime,
};
public void Start(string proxyListDirectory, string stream, bool headless, int browserLimit, int refreshInterval, string preferredQuality, ConcurrentQueue<LoginDto> loginInfos)
{
_error = false;
BrowserLimit = browserLimit;
CanRun = true;
_firstPage = true;
Headless = headless;
PreferredQuality = preferredQuality;
_refreshInterval = refreshInterval;
int i = 0;
StreamUrl = stream;
DirectoryInfo di = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory + "\\zipSource\\");
foreach (FileInfo res in di.GetFiles())
{
res.Delete();
}
foreach (DirectoryInfo dir in di.GetDirectories())
{
dir.Delete(true);
}
if (BrowserLimit > 0)
{
Thread thr = new Thread(LoopWithLimit);
thr.Start();
}
ZipDirectory = AppDomain.CurrentDomain.BaseDirectory + "\\zipSource\\background";
do
{
try
{
_file = new StreamReader(proxyListDirectory);
string line;
while (CanRun && (line = _file.ReadLine()) != null)
{
Thread.Sleep(1000);
line = line.Replace(" ", "");
if (string.IsNullOrEmpty(line))
continue;
var array = line.ToString().Split(':');
string text = File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "\\zipDirectory\\backgroundTemplate.js");
text = text.Replace("{ip}", array[0]).Replace("{port}", array[1]).Replace("{username}", array[2]).Replace("{password}", array[3]);
File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "\\zipDirectory\\background.js", text);
ZipFile.CreateFromDirectory(AppDomain.CurrentDomain.BaseDirectory + "\\zipDirectory", AppDomain.CurrentDomain.BaseDirectory + "\\zipSource\\background" + i + ".zip");
Thread thr = new Thread(Request) { Priority = ThreadPriority.Normal };
Random r = new Random();
int rInt = r.Next(3000, 6000);
while (BrowserLimit > 0 && DriverServices.Count >= BrowserLimit)
{
Thread.Sleep(1000);
}
if (!CanRun)
continue;
loginInfos.TryDequeue(out var loginInfo);
i++;
thr.Start(new SessionConfigurationDto { Url = line, Count = i, PreferredQuality = preferredQuality, LoginInfo = loginInfo});
Thread.Sleep(BrowserLimit == 0 ? rInt : 1000);
}
_file.Close();
}
catch (Exception e)
{
InitializationError?.Invoke(e is IndexOutOfRangeException
? "Please select a valid proxy file."
: $"Uppss! {e.Message}");
_error = true;
}
if (!CanRun)
break;
} while (browserLimit > 0);
if (!_error)
DidItsJob?.Invoke();
else
{
InitializationError?.Invoke("Uppss! Something went wrong");
}
}
private void StoreCookie(Tuple<string,List<Cookie>> cookie)
{
var myCookie = new List<MyCookie>();
foreach (var item in cookie.Item2)
{
if (item.Expiry != null)
myCookie.Add(new MyCookie()
{
domain = item.Domain, expiry = item.Expiry.Value.Ticks, httpOnly = item.IsHttpOnly,
name = item.Name, path = item.Path, value = item.Value, secure = item.Secure
});
else
{
myCookie.Add(new MyCookie()
{
domain = item.Domain,
expiry = DateTime.MaxValue.Ticks,
httpOnly = item.IsHttpOnly,
name = item.Name,
path = item.Path,
value = item.Value,
secure = item.Secure
});
}
}
lock (_lockObject)
{
if (!File.Exists(_loginCookiesPath))
{
var item = new Dictionary<string, List<MyCookie>> { { cookie.Item1, myCookie } };
File.WriteAllText(_loginCookiesPath, Newtonsoft.Json.JsonConvert.SerializeObject(item), Encoding.UTF8);
return;
}
string readCookiesJson = File.ReadAllText(_loginCookiesPath);
var readCookies = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, List<MyCookie>>>(readCookiesJson);
readCookies.TryGetValue(cookie.Item1, out var value);
if (value?.Count > 0)
{
readCookies[cookie.Item1] = myCookie;
}
else
readCookies.Add(cookie.Item1, myCookie);
File.WriteAllText(_loginCookiesPath, Newtonsoft.Json.JsonConvert.SerializeObject(readCookies), Encoding.UTF8);
}
}
private List<MyCookie> GetCookie(string username)
{
lock (_lockObject)
{
if (!File.Exists(_loginCookiesPath))
{
return new List<MyCookie>();
}
string readCookiesJson = File.ReadAllText(_loginCookiesPath);
var readCookies = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, List<MyCookie>>>(readCookiesJson);
return readCookies.FirstOrDefault(x => x.Key == username).Value;
}
}
private void KillAllProcesses()
{
string strCmd = "";
Process.Start("CMD.exe", strCmd);
//foreach (var driverService in DriverServices)
//{
// while (true)
// {
// try
// {
// if (!driverService.IsRunning)
// break;
// strCmdText = "/C taskkill /F /PID " + Process.GetProcessById(driverService.ProcessId);
// Process.Start("CMD.exe", strCmdText);
// break;
// }
// catch (Exception ex)
// {
// //ignored
// }
// }
//}
strCmd = "";
Process.Start("CMD.exe", strCmd);
}
private void KillAllProcesses2()
{
string strCmd = "" + " /F";
Process.Start("CMD.exe", strCmd);
//foreach (var driverService in DriverServices)
//{
// while (true)
// {
// try
// {
// if (!driverService.IsRunning)
// break;
// strCmdText = "/C taskkill /F /PID " + Process.GetProcessById(driverService.ProcessId);
// Process.Start("CMD.exe", strCmdText);
// break;
// }
// catch (Exception ex)
// {
// //ignored
// }
// }
//}
strCmd = "" + " /F";
Process.Start("CMD.exe", strCmd);
}
public void Stop()
{
CanRun = false;
_file.Close();
KillAllProcesses2();
var files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "\\zipSource");
foreach (var file in files)
{
File.Delete(file);
}
DriverServices.Clear();
AllBrowsersTerminated?.Invoke();
}
private void LoopWithLimit()
{
while (CanRun)
{
try
{
if(DriverServices.Count >= BrowserLimit)
{
KillAllProcesses();
DriverServices.Clear();
}
Thread.Sleep(500);
}
catch (Exception)
{
//ignored
}
}
}
private void Request(object obj)
{
try
{
Random r = new Random();
SessionConfigurationDto itm = (SessionConfigurationDto)obj;
var array = itm.Url.Split(':');
var driverService = ChromeDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
Proxy proxy = new Proxy
{
Kind = ProxyKind.Manual
};
string proxyUrl = array[0] + ":" + array[1];
string proxyUrl2 = "https://google.com/" + array[4];
proxy.SslProxy = proxyUrl;
proxy.HttpProxy = proxyUrl;
StreamUrl = proxyUrl2;
var chromeOptions = new ChromeOptions { Proxy = proxy, AcceptInsecureCertificates = true };
if (Headless)
{
chromeOptions.AddArgument("headless");
}
else
chromeOptions.AddExtension(ZipDirectory + itm.Count + ".zip");
string[] resolutions = { "960,720", "1080,720", "1280,800", "1280,720", "960,600", "1024,768", "800,600" };
chromeOptions.AddArgument("window-size=" + resolutions[r.Next(0, resolutions.Length - 1)]);
chromeOptions.AddArgument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36");
chromeOptions.AddArgument("mute-audio");
chromeOptions.AddExcludedArgument("enable-automation");
chromeOptions.AddAdditionalCapability("useAutomationExtension", false);
chromeOptions.PageLoadStrategy = PageLoadStrategy.Default;
DriverServices.Enqueue(driverService);
var startDate = DateTime.Now;
Thread.Sleep(600);
var driver = new ChromeDriver(driverService, chromeOptions, TimeSpan.FromSeconds(9999)) { Url = StreamUrl };//"https://www.twitch.tv/"+ Guid.NewGuid() };
if (Headless)
{
IJavaScriptExecutor js = driver;
Thread.Sleep(3000);
Thread.Sleep(30000);
try
{
}
catch (Exception)
{
}
}
if (BrowserLimit > 0)
{
Thread.Sleep(1000);
return;
}
bool matureClicked = false;
int matureCheckCount = 0;
bool cacheClicked = false;
int cacheCheckCount = 0;
if (itm.LoginInfo != null)
{
Thread.Sleep(1000);
var allCookies = GetCookie(itm.LoginInfo.Username);
if (allCookies != null)
{
foreach (var cookie in allCookies)
{
driver.Manage().Cookies.AddCookie(new Cookie(cookie.name,cookie.value,cookie.domain,cookie.path, new DateTime(ticks:cookie.expiry)));
}
}
try
{
var loginButton = driver.FindElementByXPath(
"/html/body/div[1]/div/div[2]/nav/div/div[3]/div[3]/div/div[1]/div[1]/button/div/div");
if (loginButton != null)
{
loginButton.Click();
Thread.Sleep(1000);
var usernameBox = driver.FindElementByXPath(
"/html/body/div[3]/div/div/div/div/div/div[1]/div/div/div[3]/form/div/div[1]/div/div[2]/input");
if (usernameBox != null)
{
usernameBox.Click();
Thread.Sleep(1000);
usernameBox.SendKeys(itm.LoginInfo.Username);
var passwordBox = driver.FindElementByXPath(
"/html/body/div[3]/div/div/div/div/div/div[1]/div/div/div[3]/form/div/div[2]/div/div[1]/div[2]/div[1]/input");
if (passwordBox != null)
{
passwordBox.Click();
Thread.Sleep(1000);
passwordBox.SendKeys(itm.LoginInfo.Password);
Thread.Sleep(1000);
var login = driver.FindElementByXPath(
"/html/body/div[3]/div/div/div/div/div/div[1]/div/div/div[3]/form/div/div[3]/button/div/div");
Thread.Sleep(1000);
login?.Click();
}
}
}
}
catch (Exception ex)
{
LogMessage?.Invoke($"Login failed: {ex}");
}
while (true)
{
Thread.Sleep(1000);
var cookie = driver.Manage().Cookies.GetCookieNamed("auth-token");
if (!string.IsNullOrEmpty(cookie?.Value))
{
StoreCookie(new Tuple<string, List<Cookie>>(itm.LoginInfo.Username, new List<Cookie>(driver.Manage().Cookies.AllCookies)));
break;
}
}
}
IncreaseViewer?.Invoke();
try
{
bool firstPage = false;
while (true)
{
try
{
if (_firstPage)
{
firstPage = true;
_firstPage = false;
}
if (firstPage)
{
var liveViewers = driver.FindElementByXPath(
"/html/body/div[1]/div/div[2]/div[1]/main/div[2]/div[3]/div/div/div[1]/div[1]/div[2]/div/div[1]/div/div/div/div[2]/div[2]/div[2]/div/div/div[1]/div[1]/div/p/span");
if (liveViewers != null)
{
LiveViewer.Invoke(liveViewers.Text);
Thread.Sleep(1000);
}
}
}
catch (Exception)
{
LiveViewer.Invoke("N/A");
}
Thread.Sleep(999);
try
{
if (!matureClicked && matureCheckCount < 5)
{
try
{
var mature = driver.FindElementByXPath(
"/html/body/div[1]/div/div[2]/div[1]/main/div[2]/div[3]/div/div/div[2]/div/div[2]/div/div/div/div/div[5]/div/div[3]/button/div/div");
mature?.Click();
matureClicked = true;
matureCheckCount++;
}
catch
{
//ignored because there is no mature button
}
}
}
catch (Exception)
{
// ignored
}
try
{
if (!cacheClicked && cacheCheckCount < 5)
{
try
{
var cache = driver.FindElementByXPath("/html/body/div[1]/div/div[2]/div[1]/div/div/div[3]/button/div/div/div");
if (cache != null)
{
cache.Click();
cacheClicked = true;
}
cacheCheckCount++;
}
catch (Exception)
{
//ignored because there is no cache button
}
}
}
catch (Exception)
{
// ignored
}
if (_refreshInterval != 0 && DateTime.Now - startDate > TimeSpan.FromMinutes(_refreshInterval))
{
driver.Navigate().Refresh();
IJavaScriptExecutor js = driver;
Thread.Sleep(3000);
Thread.Sleep(40000);
try
{
if (Button != null)
{
}
}
catch (Exception)
{
}
startDate = DateTime.Now;
}
}
}
catch (Exception)
{
//ignored
}
DecreaseViewer?.Invoke();
try
{
driver.Quit();
}
catch (Exception)
{
//ignored
}
}
catch (Exception)
{
}
}
private class MyCookie
{
public bool secure { get; set; }
public bool httpOnly { get; set; }
public string name { get; set; }
public string value { get; set; }
public string domain { get; set; }
public string path { get; set; }
public long expiry { get; set; }
}
}
public class WaitUntilNavigation
{
}
}
SessionConfigurationDto.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace BotCore.Dto
{
public class SessionConfigurationDto
{
public string Url { get; set; }
public int Count { get; set; }
public string PreferredQuality { get; set; }
public LoginDto LoginInfo { get; set; }
}
}