如何从多个网站异步获取数据并将其添加到集合中?

时间:2017-12-13 07:48:23

标签: c# multithreading async-await

我试图同时调用许多不同的Web服务并聚合数据。

我的目的是为每个Web调用创建一个Task,将共享容器传递给每个任务,并将每个调用的数据存储在容器中。只要我可以从每个Web调用中获取数据到共享容器中,我很高兴。

我已经创建了一个我正在尝试做的示例 - 但是,它有时会在Task.WaitAll行上发生异常崩溃:“发生了一个或多个错误。(源数组不够长。检查源代码index,length和数组的下限。 参数名称:sourceArray)“。

我是使用async / await和多线程的新手。

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

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Starting tasks...");
            List<Task> tasks = new List<Task>();
            List<char> container = new List<char>();
            for (int i = 0; i < 80; i++)
            {
                tasks.Add(LongTask(container));
            }
            Task.WaitAll(tasks.ToArray());
            Console.WriteLine("Checkpoint 1.");
            Console.WriteLine("Tasks Finished");

            Console.ReadLine();
        }

        public static async Task<string> LongTask(List<char> container)
        {
            var client = new HttpClient();
            var text = await client.GetAsync("http://www.google.com");

            var myList = text.StatusCode.ToString().ToList();

            container.AddRange(myList);

            return text.StatusCode.ToString();
        }
    }
}

1 个答案:

答案 0 :(得分:3)

在添加也可以使用的数据时,您可以在当前列表周围使用lock构造。

下面的

将进入班级

private static object _lock = new object();

这将在您的方法中

var myList = text.StatusCode.ToString().ToList();
lock(_lock)
{
  container.AddRange(myList);
}

或您可以使用ConcurrentBag

所以在你的代码中用main方法替换List,在main方法

ConcurrentBag<string> container = new ConcurrentBag<string>();

并在LongTask中(方法如下所示。

 var myList = text.StatusCode.ToString().ToList();               
 container.AddRange(myList);

这里我建议您将ConcurrentBag作为AddRange的字符串列表具有foreach方法,如果您确实写ConcurrentBag以添加char,则可能是其他线程也可能在中间添加string,而不是在完成所有内容后,您可以从ConcurrentBag中取出ConcurrentBag<T>并将其转换为字符数组或列表。

注意: SELECT * FROM...是一个线程安全的包实现,针对同一个线程生成和使用存储在包中的数据的情况进行了优化。