嵌套异步下载 - 内异步异步 [英] Nested Async Download - Async within Async
问题描述
我有一些嵌套的异步方法调用对方,这是令人困惑的。我想,这将下载的异步下载文件的项目进行转换。
下载按钮的点击,这是触发方式:
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("'", "'");
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:
- 您不应该使用
Task.Run
。主要用例Task.Run
是移动CPU绑定的工作,掀起了GUI线程,因此它不会阻止用户界面。我对正确使用Task.Run
是进入这个细节。 - 您应该使用一致的异步模式,最好 TAP 。您code目前正在使用TAP无处不在的除了的在
_InetGetHTMLSearchAsync
,这是使用的 EAP 。这是什么原因造成你所看到的古怪行为。
- You shouldn't be using
Task.Run
. The primary use case forTask.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 ofTask.Run
that goes into this in detail. - 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("'", "'");
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屋!