通过多次调用将变量传递给事件侦听器

时间:2013-09-15 11:46:56

标签: c# windows-phone-8 event-handling

在按钮事件功能中,我有一个多个链接来下载多个文件。要下载这些文件我有这段代码:

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

在OpenReadCompletedEventArgs的以下函数中,我需要知道哪个文件的下载已经完成:

    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语句的每次调用中发生变化,我也尝试将变量发送为+ =(sender,eventArgs)=&gt; 但我等待我的代码迫使我将按钮功能更改为async

2 个答案:

答案 0 :(得分:2)

OpenReadAsync超载需要“userToken”参数。它是为此目的而设计的。

调用OpenReadAsync时,请将此重载与变量一起使用:

client.OpenReadAsync(new Uri(itemLinks[l]), fileName);

然后,在事件处理程序中,检索它:

void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    string fileName = (string)e.UserState;

    // ...
}

答案 1 :(得分:0)

由于您使用的是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);