【发布时间】:2015-06-10 10:28:10
【问题描述】:
我有以下方法用于下载文件内容:
public async Task<String> DownloadFileService(String filePath, string id)
{
string resposta = string.Empty;
try
{
using (var httpClient = new HttpClient { BaseAddress = Constants.baseAddress })
{
string token = App.Current.Resources["token"] as string;
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
string fname = Path.GetFileName(filePath);
string path = Path.GetDirectoryName(filePath);
path = path.Replace(fname, "");
StorageFolder folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(Constants.DataDirectory + "\\" + path, CreationCollisionOption.OpenIfExists);
StorageFile imgFile = await folder.CreateFileAsync(fname, CreationCollisionOption.ReplaceExisting);
using (var response2 = await httpClient.GetAsync("file?fileId=" + id))
{
Stream imageStream = await response2.Content.ReadAsStreamAsync();
byte[] bytes = new byte[imageStream.Length];
imageStream.Read(bytes, 0, (int)imageStream.Length);
await FileIO.WriteBytesAsync(imgFile, bytes);
resposta = Convert.ToBase64String(bytes);
}
}
return resposta;
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
我想知道如何多次调用它来同时下载多个文件并等到所有文件都下载完毕,然后再做其他事情。
编辑
在this 建议后,我尝试创建以下方法:
public async void checkFilesExist(JsonArray array, string path)
{
List<Document> list = new List<Document>();
ObjectsService obj = new ObjectsService();
List<Task> ts = new List<Task>();
foreach (var item in array)
{
JsonObject newDoc;
JsonObject.TryParse(item.Stringify(), out newDoc);
if (newDoc.ContainsKey("libraryType") || !newDoc.ContainsKey("fileName"))
continue;
string name = newDoc["fileName"].GetString();
string id = newDoc["_id"].GetString();
File file = new File(name);
file.id = id;
Document doc = file;
doc.Parent = Document.FromPath(path);
path = path.Replace("/", "\\");
StorageFolder folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(Constants.DataDirectory + "\\" + path, CreationCollisionOption.OpenIfExists);
try
{
await folder.GetFileAsync(file.Name);
}
catch (Exception e)
{
list.Add(doc);
Task x = obj.DownloadFileService(doc.GetFullPath(), file.id);
ts.Add(x);
Debug.WriteLine(" Ex: " + e.Message);
}
}
try
{
Task.WaitAll(ts.ToArray());
Debug.WriteLine("AFTER THrEADS");
}
catch (Exception e)
{
Debug.WriteLine("Ex2: " + e.Message);
}
}
这样做是,通过我从列出一些文件的 web 服务获得的 json 响应,我检查它们是否已经存在于本地文件夹中。 如果他们不这样做,我会调用我在问题开始时使用的方法。
然后我有一个任务列表,我将DownloadFileService() 的调用添加为列表中的新任务,然后我执行Task.WaitAll() 以等待下载完成。
使用提琴手我看到下载都开始了,但由于某种原因,我的代码并没有在Task.WaitAll() 停止,它只是继续运行并开始使用仍在下载的文件,从而产生了一堆问题: D
【问题讨论】:
-
你试过调试你的代码吗?在
Task.WaitAll(ts.ToArray());行放一个断点,看看代码是否到达那里。 -
有一些断点,我看到的行为类似于,它到达等待文件夹。GetFileAsync(file.Name);然后它在 checkFilesExist 方法调用之后执行代码,然后在文件夹之后进入 catch 中的代码。GetFileAsync(file.Name);
-
好的,所以我将 Task.WaitAll 更改为 await Task.WhenAll,它现在似乎可以工作了。
标签: c# .net multithreading windows-store-apps httpclient