真正的并行下载

时间:2011-07-16 08:35:08

标签: c# .net windows download webclient

此方法用于并发下载。

public void DownloadConcurrent(Action Method)
        {
            Action[] methodList = new Action[Concurent_Downloads];

            for (int i = 0; i < Concurent_Downloads; i++)
            {
                methodList[i] = Method;
            }

            Parallel.Invoke(methodList);
        }

我正在尝试同时下载网址,但有效下载的数量始终是一个。

就像所有下载都会调用一样,但只有一个url会开始下载数据,而不是所有下载都会开始下载。

我希望所有下载同时并行工作,无法实现。

更新:方法正在使用队列,它正在下载不同的URL,形成队列。

2 个答案:

答案 0 :(得分:13)

WebClient的实例成员不是线程安全的,因此请确保每个操作中都有单独的实例。在您显示的方法中,您似乎多次将相同的操作委托相乘。所以你没有下载不同的网址,你多次下载相同的网址。并且因为WebClient不是线程安全的,所以您可能会遇到问题。

以下是使用TPL并行下载多个网址的示例:

using System;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        var urls = new[] 
        { 
            "http://google.com", 
            "http://yahoo.com", 
            "http://stackoverflow.com" 
        };

        var tasks = urls
            .Select(url => Task.Factory.StartNew(
                state => 
                {
                    using (var client = new WebClient())
                    {
                        var u = (string)state;
                        Console.WriteLine("starting to download {0}", u);
                        string result = client.DownloadString(u);
                        Console.WriteLine("finished downloading {0}", u);
                    }
                }, url)
            )
            .ToArray();

        Task.WaitAll(tasks);
    }
}

答案 1 :(得分:4)

要改进@ Darin-Dimitrov的答案,您可以使用此改进的功能从original form检索protected void Page_Load(object sender, EventArgs e) { GridView grd = grdTest; //grdTest is Id of gridview BindGrid(grd); } public static void BindGrid(GridView grd) { using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString)) { SqlCommand cmd = new SqlCommand("select* from testtable", con); SqlDataAdapter adapter = new SqlDataAdapter(cmd); DataTable dt = new DataTable(); adapter.Fill(dt); grd.DataSource = dt; grd.DataBind(); } } 以在其他地方使用:

result