我必须下载并将大量图像保存到本地文件夹。此外,我必须在下载图像时更新UI。现在我使用以下代码逐个下载图像。但问题是每个下载请求都会阻止UI。我该如何处理下载方法?我对线程知之甚少。任何人都可以用一个好方法帮助我吗?
public async Task<T> ServiceRequest<T>(string serviceurl, object request)
{
string response = "";
httpwebrequest = WebRequest.Create(new Uri(serviceurl)) as HttpWebRequest;
httpwebrequest.Method = "POST";
httpwebrequest.ContentType = "application/json";
byte[] data = Serialization.SerializeData(request);
using (var requestStream = await Task<Stream>.Factory.FromAsync(httpwebrequest.BeginGetRequestStream, httpwebrequest.EndGetRequestStream, null))
{
await requestStream.WriteAsync(data, 0, data.Length);
}
response = await httpRequest(httpwebrequest);
var result = Serialization.Deserialize<T>(response);
return result;
}
public async Task<string> httpRequest(HttpWebRequest request)
{
try
{
string received;
using (var response = (HttpWebResponse)(await Task<WebResponse>.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null)))
{
using (var responseStream = response.GetResponseStream())
{
using (var sr = new StreamReader(responseStream))
{
received = await sr.ReadToEndAsync();
}
}
response.Close();
}
return received;
}
catch(Exception ex)
{
return "";
}
}
答案 0 :(得分:2)
我建议你使用System.Net.Http.HttpClient
。您可以从Nuget获取它,只需选择搜索选项以包含预发布通道。虽然有一个问题:它尚未正式发布,因此您现在无法在生产代码中使用它。关于什么时候最终会被释放,没有任何消息。但如果你只是在学习,你可以自由地使用它。它使你描述的事情非常简单。这是我的代码中的一个示例,通过巧合巧合:),完全符合您的要求:
private IEnumerable<string> CountPictures(int from, int to, string folder)
{
for (int i = from; i < to; i++)
yield return string.Format("{0}/image{1}.jpg", folder, i.ToString("D2"));
}
private async Task ImportImages()
{
HttpClient c = new HttpClient();
int count = 0;
c.BaseAddress = new Uri("http://www.cs.washington.edu/research/imagedatabase/groundtruth/", UriKind.Absolute);
foreach (var pic in CountPictures(1, 48, "leaflesstrees"))
{
var pic_response = await c.GetAsync(pic, HttpCompletionOption.ResponseContentRead);
if (pic_response.IsSuccessStatusCode)
{
await SaveImageAsync(pic.Replace('/', '_'), await pic_response.Content.ReadAsStreamAsync());
Debug.WriteLine(pic + " imported");
count++;
}
}
Debug.WriteLine(string.Format("{0} images imported", count));
}
private Task SaveImageAsync(string filename, Stream stream)
{
var task = Task.Factory.StartNew(() =>
{
if (stream == null || filename == null)
{
throw new ArgumentException("one of parameters is null");
}
try
{
using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream targetStream = isoStore.OpenFile(filename, FileMode.Create, FileAccess.Write))
{
byte[] readBuffer = new byte[4096];
int bytesRead = -1;
stream.Position = 0;
targetStream.Position = 0;
while ((bytesRead = stream.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
targetStream.Write(readBuffer, 0, bytesRead);
}
}
}
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("DocumentStorageService::LoadImage FAILED " + e.Message);
}
});
return task;
}
为了显示隔离存储中的图像,您可以参考我的回答here中描述的方法之一。