首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >嵌套异步下载-异步内的异步

嵌套异步下载-异步内的异步
EN

Stack Overflow用户
提问于 2016-04-24 19:28:40
回答 1查看 239关注 0票数 0

我有一些嵌套的异步方法相互调用,这是令人困惑的。我正在尝试转换一个下载异步下载文件的项目。在单击“下载”按钮时,这是触发的方法:

代码语言:javascript
复制
private async void enableOfflineModeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            for(int i = 0; i < _playlists.Count; i++)
            {
                DoubleDimList.Add(new List<String>());
                for(int j = 0; j < 5; j++)
                {
                    string sMp3 = IniReadValue(_playlists[i], "Track " + j);
                    DoubleDimList[i].Add(sMp3);
                }
                await Task.Run(() =>  _InetGetHTMLSearchAsyncs(DoubleDimList[i]));              
            }
        }

它创建了一个2d List,最终看起来像这个DoubleDimList[3][20]。在每个sublist的末尾,您可以看到,我正在下载async。该方法如下所示

代码语言:javascript
复制
private async Task _InetGetHTMLSearchAsyncs(List<string> urlList)
        {
            foreach (var url in urlList)
            {
                await Task.Run(() => _InetGetHTMLSearchAsync(url));
            }
        }

_InetGetHTMLSearchAsync方法看起来像这样,这里是它变得棘手的地方。

代码语言:javascript
复制
private async Task _InetGetHTMLSearchAsync(string sTitle)
        {
            Runs++;
            if (AudioDumpQuery == string.Empty)
            {
                //return string.Empty;
            }
            string sResearchURL = "http://www.audiodump.biz/music.html?" + AudioDumpQuery + sTitle.Replace(" ", "+");
            try
            {
                using (var client = new WebClient())
                {
                    client.Headers.Add("Referer", @"http://www.audiodump.com/");
                    client.Headers.Add("user-agent", "Mozilla / 5.0(Macintosh; Intel Mac OS X 10_9_3) AppleWebKit / 537.75.14(KHTML, like Gecko) Version / 7.0.3 Safari / 7046A194A");
                    client.DownloadStringCompleted += Client_DownloadStringCompleted;
                    await Task.Run(() => client.DownloadStringAsync(new Uri(sResearchURL)));

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Debug message: " + ex.Message + "InnerEx: " + ex.StackTrace);
                Console.WriteLine("Runs: " + Runs);
                return;
            }
        }

Client_DownloadStringCompleted上有另一个名为async的方法。就是这里

代码语言:javascript
复制
private async void Client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            string[] sStringArray;
            string aRet = e.Result;
            string[] aTable = _StringBetween(aRet, "<BR><table", "table><BR>", RegexOptions.Singleline);
            if (aTable != null)
            {
                string[] aInfos = _StringBetween(aTable[0], ". <a href=\"", "<a href=\"");
                if (aInfos != null)
                {
                    for (int i = 0; i < 1; i++)
                    {
                        sStringArray = aInfos[i].Split('*');
                        sStringArray[0] = sStringArray[0].Replace("&#39;", "'");
                        aLinks.Add(sStringArray[0]);
                    }
                    await Task.Run(() => DownloadFile(aLinks[FilesDownloaded]));
                }
            }
        }

从那开始,惊喜!另一个async电话。

代码语言:javascript
复制
private async Task DownloadFile(string url)
        {
            try
            {
                using (var client = new WebClient())
                {
                    client.Headers.Add("Referer", @"http://www.audiodump.biz/");
                    client.Headers.Add("user-agent", "Mozilla / 5.0(Macintosh; Intel Mac OS X 10_9_3) AppleWebKit / 537.75.14(KHTML, like Gecko) Version / 7.0.3 Safari / 7046A194A");
                    client.DownloadFileCompleted += Client_DownloadFileCompleted;
                    await Task.Run(() => client.DownloadFileTaskAsync(url, mp3Path + "\\" + count + ".mp3"));

                }
            }
            catch (Exception Ex)
            {
                Console.WriteLine("File download error: " + Ex.StackTrace);
            }
        }

现在,创建2d List后的第一部分是检索mp3s的下载链接。第二部分是在提供了有效的mp3后立即下载URL。它起作用了,但以一种奇怪的方式。而不是正常下载文件(1,2,3.),它将随机下载文件(1,5,8.)。

这是我第一次下载async,男孩,我已经远离我的极限了。

我在哪里搞砸了?而主要的问题是,这是否会像它应该的那样运作呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-25 03:47:48

您的代码看起来相当不错,除了两件事:

  1. 你不应该使用Task.RunTask.Run的主要用例是将CPU绑定的工作移出GUI线程,这样它就不会阻塞UI。我有一个关于Task.Run的系列,详细介绍了这一点。
  2. 您应该使用一致的异步模式,最好是水龙头。您的代码目前在任何地方都使用TAP,但在_InetGetHTMLSearchAsync中除外,后者使用EAP。这就是导致你所看到的奇怪行为的原因。

固定的_InetGetHTMLSearchAsync看起来如下所示:

代码语言:javascript
复制
private async Task _InetGetHTMLSearchAsync(string sTitle)
{
  Runs++;
  string sResearchURL = "http://www.audiodump.biz/music.html?" + AudioDumpQuery + sTitle.Replace(" ", "+");
  try
  {
    using (var client = new WebClient())
    {
      client.Headers.Add("Referer", @"http://www.audiodump.com/");
      client.Headers.Add("user-agent", "Mozilla / 5.0(Macintosh; Intel Mac OS X 10_9_3) AppleWebKit / 537.75.14(KHTML, like Gecko) Version / 7.0.3 Safari / 7046A194A");
      string[] sStringArray;
      string aRet = await client.DownloadStringTaskAsync(new Uri(sResearchURL));
      string[] aTable = _StringBetween(aRet, "<BR><table", "table><BR>", RegexOptions.Singleline);
      if (aTable != null)
      {
        string[] aInfos = _StringBetween(aTable[0], ". <a href=\"", "<a href=\"");
        if (aInfos != null)
        {
          for (int i = 0; i < 1; i++)
          {
            sStringArray = aInfos[i].Split('*');
            sStringArray[0] = sStringArray[0].Replace("&#39;", "'");
            aLinks.Add(sStringArray[0]);
          }
          await DownloadFile(aLinks[FilesDownloaded]); // Should really be called "DownloadFileAsync"
        }
      }
    }
  }
  catch (Exception ex)
  {
    Console.WriteLine("Debug message: " + ex.Message + "InnerEx: " + ex.StackTrace);
    Console.WriteLine("Runs: " + Runs);
    return;
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36827867

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档