创建多个线程并等待它们全部完成,然后再次调用以完成

本文关键字:然后 调用 全部 线程 等待 创建 | 更新日期: 2023-09-27 18:21:48

我有一个Web服务,为本地数据库加载数据库服务器,请求100条记录。

由于这个过程很慢,我想创建十个线程,不要占用太多内存,进行Web服务调用,当其中一个线程完成时,会有100多条调用记录。部分线程如何处理?

示例:

创建线程1创建线程2创建线程3创建线程4

线程1完成再次更改Web服务

编辑

我的代码不起作用。变量send总是得到值10,而不是0,1,2,3,4等。

Int32 page = 0;            
do
{                
    for (int iterator=0; iterator < 10; iterator++)
    {                    
        listTask[iterator] = Task.Factory.StartNew(() =>
        {
            Int32 send = iterator + page * 10;
            DoStatus("Page: " + send.ToString());
            Processamento(parametros, filial, send);                        
        });
    }
    Task.WaitAll(listTask);
    page++;
}
while (true); // Test only

创建多个线程并等待它们全部完成,然后再次调用以完成

您正在结束循环变量。您需要记住,lambdas关闭变量,而不是关闭值。在lambda执行iterator + page * 10时,每个任务都将读取iterator的值。当这种情况发生时,主线程已经将其递增到10

这很容易解决。在for循环中复制循环变量,以便闭包关闭该变量,该变量永远不会更改。

for (int iterator=0; iterator < 10; iterator++)
{
    int i = iterator;
    listTask[iterator] = Task.Factory.StartNew(() =>
    {
        Int32 send = i + page * 10;
        DoStatus("Page: " + send.ToString());
        Processamento(parametros, filial, send);                        
    });
}

如果我理解你的问题,你想创建10个线程,等待所有线程,然后重新创建10个,等等。每个线程加载100个结果。

在这个答案中,结果是String,但这是可以改变的。

private void Load()
{
    Boolean loading = true;
    List<String> listResult = new List<String>();
    Int32 boucle = 0;
    Task[] listTask = new Task[10];
    do
    {
        // create 10 threads (=1000 results)
        for (int iterator=0; iterator < 10; iterator++)
        {
            // [0-99] [100-199] [200-299] ...
            Int32 start = 100 * iterator + 1000 * boucle;
            Int32 end = start + 99;
            listTask[iterator] = Task<List<String>>.Factory.StartNew(() =>
            {
                List<String> data = LoadData(start, end);
                return data;
            });
        }
        // wait for 10 threads to finish
        Task.WaitAll(listTask);
        // collapse results
        for (int i=0; i < 10; i++)
        {
            listResult.AddRange((listTask[i] as Task<List<String>>).Result);
        }
        // check if there is 100 results in last thread
        loading = (listTask[9] as Task<List<String>>).Result.Count == 100;
        // ready for another iteration (next 1000 results)
        boucle++;
    }
    while (loading);
}
private List<string> LoadData(int p1, int p2)
{
    // TODO : load data from p1 to p2
    throw new NotImplementedException();
}