如何在C# .Net 4.5.1中迭代调用一个方法而无需等待方法响应?

3

首先,我为那个问题的措辞道歉……这是情景:

我建立了一个WEB API方法,它接收一个ProductID,然后将该产品的图像上传到Amazon S3。这部分工作非常顺利。

现在,我正在尝试运行一个控制台应用程序,它将获取一系列ProductIDs并循环遍历它们,调用API方法,并且不等待结果……

有人能指点我正确的方向吗?

我想另一个警告是不要占用运行控制台应用程序的机器上的所有资源……所以可能需要线程限制?

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

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);
        }
    }
}

3
将你的 Web API 方法制作成异步版本并使用这些方法。如果不可能,就从单独的任务/线程中调用这些方法。 - Jeff Mercado
你是否查看过使用C#的异步API的亚马逊AWS文档 - Lukazoid
除非你确定必须这样做,并且在此时它是正确的选项,否则不要创建“async void”方法。通常情况下不建议这样做。你几乎总是应该返回一个“Task”。 - Servy
2个回答

2
有几种简单的方法可以做到这一点。
我建议使用 Parallels。它可以最优化地利用您的环境中的多个线程/核心。对于您的示例,您只需执行以下操作:
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());

-1

我不建议使用Parallel.For。它不能很好地控制并行性(您可能不想一直发送数百个请求,这些请求将开始超时),而且它需要不必要的上下文切换。

线程/核心不是处理HTTP请求的限制因素。

在示例中进行更改。

Thread.Sleep(2000)

await Task.Delay(2000)

当使用真实的 Web API 调用时

await httpClient.PostAsync(...)

还要记得在主函数中等待

Console.ReadLine() // or something more sophisticated

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接