Foreach执行异步下载不能正常工作
本文关键字:工作 常工作 执行 异步 下载 不能 Foreach | 更新日期: 2023-09-27 18:03:48
我的应用程序从文本文件生成一个字符串数组,并在类中调用一个方法填充字符串,调用它作为变量使用,如:
void listafile()
{
WebClient client1 = new WebClient();
client1.DownloadFile(new Uri("http://www.example.com/pack/content"), @".'pack'content");
string[] lines = System.IO.File.ReadAllLines(@".'pack'content");
foreach (string Pacchetto in lines)
{
startDownload(Pacchetto);
}
startDownload (Pacchetto);是一个方法调用,在它里面我使用webclient对象与Async下载下载每个文件从数组。
所有似乎工作50%,但当异步下载开始时,Foreach循环产生大量下载,他们在完成前杀死自己。
void startDownload(string Pacchetto)
{
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
client.DownloadFileAsync(new Uri("http://www.example.com/pack/"+ Pacchetto), @".'pack'" + Pacchetto);
}
你知道如何让每个周期等待下载完成后再开始另一个周期,而不会阻塞所有的程序与"客户端"吗?下载文件"这不是异步的?在这个类中,也有一个进度条和一个标签来显示下载的进度
我会使用微软的响应式框架(NuGet "Rx-Main")。
首先,我要创建一个函数,它接受一个字符串(URL)并返回一个string对象:
Func<string, IObservable<string>> downloadStringObservable =
u =>
Observable.Using(
() => new WebClient(),
wc => Observable.Start(() => wc.DownloadString(u)));
现在我可以写一个非常简单的查询:
var query =
from x in downloadStringObservable("http://www.example.com/pack/content")
from y in x.Split(
Environment.NewLine.ToCharArray(),
StringSplitOptions.RemoveEmptyEntries).ToObservable()
from z in downloadStringObservable(y)
select new
{
url = y,
data = z
};
我可以像这样异步访问查询的结果:
query
.Subscribe(x =>
{
/* do something with `x.url` & `x.data` */
});
现在,如果你正在使用WinForms或WPF,你需要观察UI线程上的结果。这就像在Subscribe
:
query
.ObserveOn(someExistingUIFormOrControl)
.Subscribe(x =>
{
/* do something with `x.url` & `x.data` */
});
容易。: -)
如果您希望按顺序下载文件,您可以将DownloadFileAsync
操作的结果await
。这将不会阻塞主线程,但仍按顺序下载文件
async void startDownload(string Pacchetto)
{
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
await client.DownloadFileAsync(new Uri("http://www.example.com/pack/"+ Pacchetto), @".'pack'" + Pacchetto);
}
你甚至可以在一个新线程中开始同步
new Thread(new ThreadStart(CompareVersions)).Start();