Reputation: 5621
I have the following code, used to download multiple files, create a zip file, and return the file to the user:
//In a WebAPI GET Handler
public async Task<HttpResponseMessage> Get(string id)
{
try
{
var urlList = CacheDictionary<String, List<String>>.Instance[id];
var helper = new Helper();
var zipFile = await helper.CreateZipFormUrls(urlList);
var response = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new MemoryStream();
zipFile.Save(stream);
response.Content = new ByteArrayContent(stream.ToArray());
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
response.Content.Headers.ContentLength = stream.Length;
response.Content.Headers.ContentDisposition.FileName = "download.zip";
return response;
}
catch (Exception)
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
//In a Helper Class
public async Task<ZipFile> CreateZipFromUrls(List<string> urlList)
{
using (var zip = new ZipFile())
{
var files = await ReturnFileData(urlList);
foreach (var file in files)
{
var e = zip.AddEntry(GetFileNameFromUrlString(file.Key), file.Value);
}
return zip;
}
}
static Task<Dictionary<string, byte[]>> ReturnFileData(IEnumerable<string> urls)
{
Dictionary<Uri, Task<byte[]>> dictionary;
using (var client = new WebClient())
{
dictionary = urls.Select(url => new Uri(url)).ToDictionary(
uri => uri, uri => client.DownloadDataTaskAsync(uri));
await Task.WhenAll(dictionary.Values);
}
return dictionary.ToDictionary(pair => Path.GetFileName(pair.Key.ToString()),
pair => pair.Value.Result);
}
private string GetFileNameFromUrlString(string url)
{
var uri = new Uri(url);
return System.IO.Path.GetFileName(uri.LocalPath);
}
I always get:
An asynchronous module or handler completed while an asynchronous operation was still pending
And cannot reach any breakpoints after the download method is called. What am I doing wrong? Where do I look?
Upvotes: 0
Views: 268
Reputation: 2352
Try await on this
dictionary = urls.Select(url => new Uri(url)).ToDictionary(
uri => uri, uri => client.DownloadDataTaskAsync(uri));
The problem might be that
client.DownloadDataTaskAsync(uri));
is probably still running when the rest of your code is done.
Upvotes: 1