0

我必须下载大量图像并将其保存到本地文件夹。我还必须在下载图像时更新 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 "";
    }
}
4

1 回答 1

3

我建议您使用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;
}

为了显示来自独立存储的图像,您可以参考我在此处的回答中描述的方法之一。

于 2013-04-22T09:58:50.183 回答