DownloadStringAsync的异步功能

时间:2016-11-11 09:57:42

标签: c# wpf asynchronous

我正在尝试

在我的WPF中,我抓取内部网络并查看是否可以访问IP / URL。所以我在循环中用DownloadStringAsync调用255个IP。现在,每当我收到响应或超时时,我想更新我的进度条(最多为255)。我的代码似乎适用于第一个x(我相信类似于10-15)IP,因为我看到进度条移动

致电循环

try
   {
     while (i < 255)
     {
         var client = new WebClient();
         client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(GetInfo);
         client.DownloadStringAsync(new Uri("http://" + myIPNet + "." + i + ":1400/status/topology"));
         i++;
     }
   }
   catch (Exception ex)
   {
       Console.WriteLine(ex.Message);
   }

GetInfo功能

private void GetInfo(object sender, DownloadStringCompletedEventArgs e)
{
    /* Each call, count up Global Ip Counter and move progressBar */
    countIps++;
    pbSearch.Value = countIps;

    /* Do Stuff with e.Result */
    ...

    /* Check if we have all IPs in net already */
    if (countIps == 255)
    {
        /* Reset progressBar */
        pbSearch.Value = 0;

        /* Enable Button  */
        btnGetAll.IsEnabled = true;
     }
 }

我发现了这个Asynchronous File Download with Progress Bar,我想我理解了这个答案https://stackoverflow.com/a/9459441/1092632但是这个进度条已经更新,正在进行一次下载,有关如何转换&#34;的任何想法这个我的情况?

1 个答案:

答案 0 :(得分:1)

我认为您的代码存在的主要问题是,在DownloadStringAsync事件被触发之前,您期望DownloadStringCompleted阻止。根据函数的描述,这不会发生:

  

下载指定为Uri的资源。此方法不会阻止   调用线程。

实际上,您正在快速进行255个并发Web调用,然后在完成之前删除循环的底部。

由于使用Event-based Asynchronous Pattern (EAP)进行阻止需要对代码进行重大的重新架构(并且会显着增加复杂性),因此我建议您先使用Task-based Asynchronous Pattern。 Stephen Toub有一个很好的指南,可以将WebClient从EAP转换为TAP模式here

使用此功能,您可以按如下方式重写代码,并且应该会取得更大的成功:

var client = new WebClient();

while (i < 255)
{
    try
    {
        byte[] result = await client.DownloadDataTask(new Uri("http://" + myIPNet + "." + i + ":1400/status/topology"));
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    pbSearch.Value = i++;
}

/* Now we have all IPs */
/* Reset progressBar */
pbSearch.Value = 0;

/* Enable Button  */
btnGetAll.IsEnabled = true;

希望它有所帮助。