C#多线程逐行读取文件调用Login函数的实现咨询
Alright, let's walk through how to build this properly in C# (since your Login method signature looks like C#). I'll break it down into clear, actionable steps so you can implement it without hassle:
First, we need to read the file line by line and split each line into valid username:password pairs. Your example has multiple pairs per line separated by spaces, so we'll handle both the line split and the credential split:
var credentials = new List<(string Username, string Password)>(); // Use File.ReadLines to stream lines instead of loading the whole file into memory foreach (var line in File.ReadLines("your-credential-file.txt")) { // Split the line into individual credential pairs (ignore empty entries) var credentialPairs = line.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries); foreach (var pair in credentialPairs) { var parts = pair.Split(':'); if (parts.Length == 2) { // Trim whitespace just in case there's extra spaces around the credentials credentials.Add((parts[0].Trim(), parts[1].Trim())); } else { // Log invalid entries so you can clean up your file later Console.WriteLine($"Skipping invalid credential format: {pair}"); } } }
Next, we'll process these credentials in parallel to save time. Parallel.ForEach is a straightforward choice here, and we can control the maximum number of concurrent threads to avoid overwhelming the target server:
// Adjust MaxDegreeOfParallelism based on how many concurrent requests the server can handle var parallelSettings = new ParallelOptions { MaxDegreeOfParallelism = 5 // Start with 5, tweak as needed }; Parallel.ForEach(credentials, parallelSettings, credential => { try { // Pass the parsed username and password to your Login method Login(credential.Username, credential.Password); } catch (Exception ex) { // Catch exceptions per credential so a single failure doesn't crash the whole process Console.WriteLine($"Login failed for user {credential.Username}: {ex.Message}"); } });
You mentioned handling two specific cookie cases in Login—let's flesh that out with proper HTTP request handling and cookie checking. I'll use HttpClient as an example (it's the modern way to make HTTP requests in C#):
public static void Login(string user, string pass) { // Create a new HttpClient per request (or use a static client with thread-safe configuration) using var httpClient = new HttpClient(); // Build your login request body (adjust this to match the target API's requirements) var loginPayload = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("username", user), new KeyValuePair<string, string>("password", pass) }); // Send the POST request (use .Result for simplicity here, but consider async/await for better control) var response = httpClient.PostAsync("https://your-login-endpoint.com", loginPayload).Result; // Ensure we handle HTTP errors (like 404, 500) try { response.EnsureSuccessStatusCode(); } catch (HttpRequestException ex) { Console.WriteLine($"HTTP error for user {user}: {ex.Message}"); return; } // Extract the reqCookie from the response (adjust this based on how the cookie is returned) string reqCookie = null; if (response.Headers.TryGetValues("Set-Cookie", out var cookies)) { // Grab the first cookie and strip any extra attributes (like expires, path) reqCookie = cookies.First().Split(';')[0]; } if (string.IsNullOrEmpty(reqCookie)) { Console.WriteLine($"No login cookie returned for user {user}"); return; } // Handle the cookie cases you mentioned switch (reqCookie) { case "Error1": Console.WriteLine($"Invalid credentials for user {user}"); break; case "proxy": Console.WriteLine($"Captcha error for user {user}—need to set proxy"); // Add your proxy setup logic here. For example: // httpClient.DefaultProxy = new WebProxy("http://your-proxy-address:port"); // Note: If using a static HttpClient, make sure proxy changes are thread-safe break; default: Console.WriteLine($"Login successful for user {user}"); break; } }
- Thread Safety: If you're sharing resources (like a global
HttpClientor proxy settings) across threads, make sure they're thread-safe. Using a separateHttpClientper request avoids most issues here. - Rate Limiting: Don't set
MaxDegreeOfParallelismtoo high—you don't want to get IP-banned or crash the target server. Start low and adjust based on response times. - Error Handling: We added per-request exception handling so one bad credential or failed request won't stop the entire batch.
- Memory Efficiency:
File.ReadLinesstreams the file instead of loading it all into memory, which is crucial if your credential file is large.
内容的提问来源于stack exchange,提问作者KirriDev

