在c#.Net 4.5.1中,如何在不等待方法响应的情况下迭代调用方法?

在c#.Net 4.5.1中,如何在不等待方法响应的情况下迭代调用方法?,c#,.net,.net-4.5,C#,.net,.net 4.5,首先,我为这个问题的糟糕措辞道歉……下面是一个场景: 我构建了一个WebAPI方法,该方法接收ProductID,然后将该产品的图像上传到AmazonS3。这部分工作得很好 我现在正在尝试运行一个控制台应用程序,它将获取一系列ProductID并在其中循环,调用API方法,而不是等待结果 谁能给我指出正确的方向吗 我想另一个警告是不要耗尽运行console应用程序的机器上的所有资源…所以可能需要一个线程帽 更新(这似乎仍然是同步的): class Program { async stat

首先,我为这个问题的糟糕措辞道歉……下面是一个场景:

我构建了一个WebAPI方法,该方法接收ProductID,然后将该产品的图像上传到AmazonS3。这部分工作得很好

我现在正在尝试运行一个控制台应用程序,它将获取一系列ProductID并在其中循环,调用API方法,而不是等待结果

谁能给我指出正确的方向吗

我想另一个警告是不要耗尽运行console应用程序的机器上的所有资源…所以可能需要一个线程帽

更新(这似乎仍然是同步的):

class Program
{
    async static void DoUpload(int itemid)
    {
        Console.WriteLine("Starting #:" + itemid);
        Thread.Sleep(2000); //Simulates long call to API
        Console.WriteLine("Finishing #:" + itemid);
    }
    static void Main(string[] args)
    {
        for (int i = 0; i < 20; i++)
        {
            DoUpload(i);
        }
    }
}
类程序
{
异步静态void双重加载(int itemid)
{
Console.WriteLine(“启动#:”+itemid);
Sleep(2000);//模拟对API的长调用
Console.WriteLine(“Finishing#::“+itemid);
}
静态void Main(字符串[]参数)
{
对于(int i=0;i<20;i++)
{
双倍体(i);
}
}
}

我不建议使用Parallel.For。它不能提供令人满意的并行性控制(您可能不想敲掉数以万计的请求,这些请求将开始超时),而且它还需要不必要的上下文切换

线程/核心不是http请求的限制因素

在这个例子中,我们需要改变

Thread.Sleep(2000)

当使用真正的web api调用时

await httpClient.PostAsync(...)
还要记得在大堂等

Console.ReadLine() // or something more sophisticated
否则,程序将在调用之前终止


然后,为了控制并行度,我认为最简单的解决方案是使用信号量来计算未完成调用的数量,在发出新请求之前,在主循环中等待信号量再次发出信号。

有几种简单的方法可以做到这一点

我建议使用。它可以最优化地利用环境中的多个线程/内核。例如,您只需执行以下操作:

var status = Parallel.For(0, 20, DoUpload);

while (!status.IsCompleted)
{
    //Do something while you wait
}
另一种方法是使用任务,并将每个调用作为单独的任务发送。但要小心这种方法,因为如果迭代次数过多,系统可能会因挂起的任务而过载

List<Tasks> tasks = new List<Tasks>();

for (int i = 0; i < 20; i++)
{
    var task = Task.Run(() => DoUpload(i));

    tasks.Add(task);
}

//wait for completion of all tasks
Task.WaitAll(tasks.ToArray());
List tasks=newlist();
对于(int i=0;i<20;i++)
{
var task=task.Run(()=>DoUpload(i));
任务。添加(任务);
}
//等待所有任务完成
Task.WaitAll(tasks.ToArray());

制作web API方法的异步版本并使用这些方法。如果不可能,请从单独的任务/线程调用这些方法。是否查看了使用C#的异步API的方法?不要创建
async void
方法,除非您确定必须这样做,并且这是当时的正确选项。通常不是。您几乎应该总是返回一个
任务
List<Tasks> tasks = new List<Tasks>();

for (int i = 0; i < 20; i++)
{
    var task = Task.Run(() => DoUpload(i));

    tasks.Add(task);
}

//wait for completion of all tasks
Task.WaitAll(tasks.ToArray());