在按钮事件函数中,我有一个多份链接来下载多份文件。 要下载这些文件,我有以下代码:
for (int l = 0; l < itemLinks.Count(); l++)
{
string[] sourceParts = itemLinks[l].Split('/');
string fileName = sourceParts[sourceParts.Count() - 1];
WebClient client = new WebClient();
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.OpenReadCompleted += client_OpenReadCompleted;
client.OpenReadAsync(new Uri(itemLinks[l]));
}
在OpenReadCompleteEventArgs的以下函数中,我需要知道哪个文件的下载已完成:
async void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
string pff = e.ToString();
byte[] buffer = new byte[e.Result.Length];
await e.Result.ReadAsync(buffer, 0, buffer.Length);
using (IsolatedStorageFile storageFile =
IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = storageFile
.OpenFile(FILE_NAME, FileMode.Create))
{
await stream.WriteAsync(buffer, 0, buffer.Length);
}
}
//Also I need to do some stuff here with FILE_NAME
}
如何将FILE_NAME值发送到client_OpenReadCompleted?
我无法将值保留在全局变量中,因为它会在 for 语句的每次调用中发生变化,我也尝试将变量发送为 +=(发送者,事件Args)=>但是我的代码中有等待,迫使我将按钮功能更改为异步
OpenReadAsync
有一个重载,需要"userToken"参数。它就是为此目的而设计的。
调用 OpenReadAsync
时,将此重载与变量一起使用:
client.OpenReadAsync(new Uri(itemLinks[l]), fileName);
然后,在事件处理程序中检索它:
void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
string fileName = (string)e.UserState;
// ...
}
由于您使用的是 await
,如果您使用 HttpClient
而不是 WebClient
,则可以使用更干净的解决方案:
await Task.WhenAll(itemLinks.Select(DownloadAsync));
private static async Task DownloadAsync(string itemLink)
{
string[] sourceParts = itemLinks[l].Split('/');
string fileName = sourceParts[sourceParts.Count() - 1];
using (var client = new HttpClient())
using (var source = await client.GetStreamAsync(itemLink))
using (IsolatedStorageFile storageFile = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream stream = storageFile.OpenFile(FILE_NAME, FileMode.Create))
{
await source.CopyToAsync(stream);
}
... // Use fileName
}
我不完全确定 WP8 上是否CopyToAsync
可用(它可能是 Microsoft.Bcl.Async
的一部分)。如果不是,您可以删除GetStreamAsync
行并将CopyToAsync
行替换为以下内容:
var buffer = await client.GetBytes(itemLink);
await stream.WriteAsync(buffer, 0, buffer.Length);