嵌套异步下载 - 内异步异步 [英] Nested Async Download - Async within Async

查看:237
本文介绍了嵌套异步下载 - 内异步异步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些嵌套的异步方法调用对方,这是令人困惑的。我想,这将下载的异步下载文件的项目进行转换。
下载按钮的点击,这是触发方式:

I have some nested async methods calling each other and it is confusing. I am trying to convert a project which downloads the files in an async download. On the click of the download button this is the method triggered:

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列表这在最后看起来像这样 DoubleDimList [3] [20]
在每个月底子列表我在做一个异步下载,你可以看到。该方法看起来像这样

It creates a 2d List which at the end looks like this DoubleDimList[3][20]. At the end of each sublist I am doing an async download as you can see. The method looks like this

private async Task _InetGetHTMLSearchAsyncs(List<string> urlList)
        {
            foreach (var url in urlList)
            {
                await Task.Run(() => _InetGetHTMLSearchAsync(url));
            }
        }

_InetGetHTMLSearchAsync 方法看起来像这一点,这里是它得到棘手

the _InetGetHTMLSearchAsync method looks like this and here is where it gets tricky

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 还有另外一个异步方法调用。这

On Client_DownloadStringCompleted there is another async method called. Here it is

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]));
                }
            }
        }

从那里,惊喜!另一个异步电话。

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列表之后的第一部分是检索的MP3下载链接。第二部分是要尽快有效网​​址提供了下载的MP3。它的工作原理,但在一个奇怪的方式。而不是下载文件通常(第一,第二,第三......)的,它会随机下载文件(1日,5日,8日...)。

Now the first part after the creation of the 2d List is to retrieve the download links of the mp3s. The second part is to download the mp3 as soon as a valid URL was provided. It works but in a bizarre way. Instead of downloading the file normally(1st, 2nd, 3rd...), it will download randomly the files(1st, 5th, 8th...).

这是我的第一次去异步下载和男孩,我已经远离我的极限。

It is my first go for async download and boy, I am already far from my limits.

我在哪里搞乱这个吗?而最主要的问题,将这个不断工作,它应该工作的方式?

Where am I messing this up? And the main question, will this ever work the way it is supposed to work?

推荐答案

您code相pretty好,除了两件事情:

Your code looks pretty good, except for two things:


  1. 您不应该使用 Task.Run 。主要用例 Task.Run 是移动CPU绑定的工作,掀起了GUI线程,因此它不会阻止用户界面。我对正确使用 Task.Run 是进入这个细节。

  2. 您应该使用一致的异步模式,最好 TAP 。您code目前正在使用TAP无处不在的除了的在 _InetGetHTMLSearchAsync ,这是使用的 EAP 。这是什么原因造成你所看到的古怪行为。

  1. You shouldn't be using Task.Run. The primary use case for Task.Run is for moving CPU-bound work off a GUI thread so it doesn't block the UI. I have a series on the proper use of Task.Run that goes into this in detail.
  2. You should use a consistent asynchronous pattern, ideally TAP. Your code is currently using TAP everywhere except in _InetGetHTMLSearchAsync, which is using EAP. This is what is causing the odd behavior you're seeing.

一个固定的 _InetGetHTMLSearchAsync 会是这个样子:

A fixed _InetGetHTMLSearchAsync would look something like this:

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;
  }
}

这篇关于嵌套异步下载 - 内异步异步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆