C#-通过节流并发/异步调用Web服务

C#-通过节流并发/异步调用Web服务,c#,web-services,asynchronous,C#,Web Services,Asynchronous,如何使用C#并发调用web服务x次 我有一个客户表(大约100万),我需要给一个有5000个客户的web服务打电话,返回一些信息并写入文件 我尝试过使用async/await和TPL数据流库,但代码比使用普通的旧同步方法慢得多。下面是我想要达到的目标的总结。代码将从无法标记为异步的控制台应用程序(主方法)运行 public void GenerateCustomerFile(){ var outputFileName = "MyCustomerFile.txt"; var

如何使用C#并发调用web服务x次

我有一个客户表(大约100万),我需要给一个有5000个客户的web服务打电话,返回一些信息并写入文件

我尝试过使用async/await和TPL数据流库,但代码比使用普通的旧同步方法慢得多。下面是我想要达到的目标的总结。代码将从无法标记为异步的控制台应用程序(主方法)运行

public void GenerateCustomerFile(){

     var outputFileName = "MyCustomerFile.txt";
     var customers = CustomerRepo.GetCustomers();
     var customerBatch = new List<Customer>();     

     foreach(var customer in customers){

        customerBatch.Add(customer);

        if(customerBatch.Count >= 20000){
            // Call web service concurrently (4 threads with 5000 customers each)
           // Write results to file
           customerBatch.Clear();
        }
     }
}
public void GenerateCustomerFile(){
var outputFileName=“MyCustomerFile.txt”;
var customers=CustomerRepo.GetCustomers();
var customerBatch=新列表();
foreach(客户中的var客户){
customerBatch.Add(客户);
如果(customerBatch.Count>=20000){
//并发调用web服务(4个线程,每个线程有5000个客户)
//将结果写入文件
customerBatch.Clear();
}
}
}

为什么要为此使用循环?您可以将其拆分并发送5K批

var customerBatch = CustomerRepo.GetCustomers();
const int batchSize = 5000;
var sendingTasks = Enumerable.Range(0,(customerBatch.Length/batchSize)).Select(async a=>{
   var section = customerBatch.Skip(a*batchSize).Take((a+1)*batchSize);
   await "https://lolcow.com/api/entity".PostJsonAsync(section);
});
await Task.WhenAll(sendingTasks);
我正在使用Flurl进行http请求,不确定您使用的是什么。但这应该与您正在做的一样…如果它比只执行所有这些操作都慢,那么您可能需要将批处理变大

对于关于main方法和async的问题,我通常只做一个main async并在main方法中使用wait调用它

public static async Task MainAsync(string[] args)
{
    //do stuff here
}

public static void Main(string[] args)
{
    MainAsync(args).Wait();
}

你为什么要用循环来做这个?您可以将其拆分并发送5K批

var customerBatch = CustomerRepo.GetCustomers();
const int batchSize = 5000;
var sendingTasks = Enumerable.Range(0,(customerBatch.Length/batchSize)).Select(async a=>{
   var section = customerBatch.Skip(a*batchSize).Take((a+1)*batchSize);
   await "https://lolcow.com/api/entity".PostJsonAsync(section);
});
await Task.WhenAll(sendingTasks);
我正在使用Flurl进行http请求,不确定您使用的是什么。但这应该与您正在做的一样…如果它比只执行所有这些操作都慢,那么您可能需要将批处理变大

对于关于main方法和async的问题,我通常只做一个main async并在main方法中使用wait调用它

public static async Task MainAsync(string[] args)
{
    //do stuff here
}

public static void Main(string[] args)
{
    MainAsync(args).Wait();
}

好的,我试试这个。从main方法调用这个异步代码怎么样?在不造成死锁的情况下,您是如何做到这一点的?在这种情况下,您实际上是如何限制任务的数量的?如果我有100万条记录,这不是要启动200个并发任务吗?不,它不应该,它应该优化处理任务的方式。如果这是在主方法中,则建议执行异步方法任务并等待itI,我需要确保只执行x个调用。我怎样才能做到这一点?好的,我试试这个。从main方法调用这个异步代码怎么样?在不造成死锁的情况下,您是如何做到这一点的?在这种情况下,您实际上是如何限制任务的数量的?如果我有100万条记录,这不是要启动200个并发任务吗?不,它不应该,它应该优化处理任务的方式。如果这是在主方法中,则建议执行异步方法任务并等待itI,我需要确保只执行x个调用。我怎样才能做到这一点?