You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求C#实现同时向同一页面发送多请求(如登录)的示例代码

How to Send Multiple Concurrent POST Requests in C# (Login Scenario Example)

Got it, I’ve been in your shoes before—trying to get multiple requests to fire at the same time instead of waiting for each one to finish sequentially can be tricky if you’re not using the right async patterns. Let’s break this down with a concrete example tailored to your login scenario.

Core Concept: Use Task.WhenAll with Async/Await

The most common mistake here is awaiting each individual request one by one (which runs them serially). Instead, you want to create all your async tasks first, then wait for all of them to complete at once using Task.WhenAll. This is the cleanest, most efficient way to handle concurrent requests in modern C#.

Complete Example Code

First, note that we’ll reuse a single HttpClient instance (critical for performance—creating a new one per request can exhaust connection pools):

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;

public class LoginRequestHandler
{
    // Reuse HttpClient across requests (best practice to avoid socket exhaustion)
    private static readonly HttpClient _httpClient = new HttpClient
    {
        BaseAddress = new Uri("https://your-login-api-domain.com/")
    };

    // Model to match your login API's request body structure
    public class LoginRequest
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }

    // Model to match your login API's response structure
    public class LoginResponse
    {
        public bool IsSuccess { get; set; }
        public string StatusMessage { get; set; }
    }

    // Async method to send one login request and return its status
    private async Task<(bool Success, string Message)> SendSingleLoginRequest(LoginRequest request)
    {
        try
        {
            var response = await _httpClient.PostAsJsonAsync("api/auth/login", request);
            response.EnsureSuccessStatusCode(); // Throws if HTTP status is 4xx/5xx
            
            var loginResult = await response.Content.ReadFromJsonAsync<LoginResponse>();
            return (loginResult.IsSuccess, loginResult.StatusMessage);
        }
        catch (HttpRequestException ex)
        {
            // Catch request-specific errors without breaking other requests
            return (false, $"Request failed: {ex.Message}");
        }
    }

    // Method to send 10 concurrent login requests and process results
    public async Task RunConcurrentLoginTests()
    {
        // Prepare 10 test login requests (customize these as needed)
        var loginRequests = new List<LoginRequest>();
        for (int i = 0; i < 10; i++)
        {
            loginRequests.Add(new LoginRequest
            {
                Username = $"test_user_{i}",
                Password = "secure_test_pass_123"
            });
        }

        // Create a list of tasks (this kicks off all requests in parallel)
        var loginTasks = new List<Task<(bool Success, string Message)>>();
        foreach (var request in loginRequests)
        {
            loginTasks.Add(SendSingleLoginRequest(request));
        }

        // Wait for all tasks to complete (this is where concurrency happens)
        var results = await Task.WhenAll(loginTasks);

        // Loop through results to check each request's status
        for (int i = 0; i < results.Length; i++)
        {
            var result = results[i];
            Console.WriteLine($"Request {i+1}: {(result.Success ? "SUCCESS" : "FAILURE")} - {result.Message}");
        }
    }
}

// To execute the code:
// var handler = new LoginRequestHandler();
// await handler.RunConcurrentLoginTests();

Key Notes to Avoid Common Pitfalls

  • Reuse HttpClient: Never create a new HttpClient for each request—this leads to socket exhaustion. The static instance above works, or you can use dependency injection in ASP.NET apps.
  • Don’t await tasks in a loop: If you did foreach (var request in loginRequests) { await SendSingleLoginRequest(request); }, that would run requests one after another, not concurrently.
  • Isolate request errors: By catching exceptions inside SendSingleLoginRequest, a single failed request won’t take down all the others. You’ll get a failure status for that specific request while others continue.
  • Results stay in order: The results array matches the order of the loginTasks list, so you can easily map each result back to its original request.

Why Raw Threads Didn’t Work for You

If you tried using raw threads, you were probably missing the async/await integration, or manual thread management gets messy fast. Task.WhenAll uses the thread pool efficiently without you having to handle thread creation and cleanup—it’s the modern, recommended approach for concurrent I/O operations in C#.

内容的提问来源于stack exchange,提问作者Programmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:45:43