异步将图像从Url加载到PictureBox

ara*_*ara 3 .net c# webrequest picturebox winforms

我想在Windows窗体应用程序上从Web加载图像,一切都很好,代码工作正常,但问题是应用程序停止工作,直到加载完成.我希望看到并使用应用程序,而无需等待加载.

PictureBox img = new System.Windows.Forms.PictureBox();
var request = WebRequest.Create(ThumbnailUrl);

using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
{
    img.Image = Bitmap.FromStream(stream);
}
Run Code Online (Sandbox Code Playgroud)

Rez*_*aei 7

PictureBoxcontrol具有内置支持,可以异步加载图像.您不需要使用BackgroundWorker或async/await.它还可以从URL加载图像,因此您无需使用Web请求.

您可以简单地使用LoadAsync方法或ImageLocation属性PictureBox.WaitOnLoad属性的值应该是false,这是默认值.

pictureBox1.LoadAsync("https://i.stack.imgur.com/K4tAc.jpg");
Run Code Online (Sandbox Code Playgroud)

它相当于:

pictureBox1.ImageLocation = "https://i.stack.imgur.com/K4tAc.jpg";
Run Code Online (Sandbox Code Playgroud)


Yas*_*osh 6

解决方法如下:

public async Task<Image> GetImageAsync(string url)
{
    var tcs = new TaskCompletionSource<Image>();
    Image webImage = null;
    HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
    request.Method = "GET";
    await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null)
        .ContinueWith(task =>
        {
            var webResponse = (HttpWebResponse) task.Result;
            Stream responseStream = webResponse.GetResponseStream();
            if (webResponse.ContentEncoding.ToLower().Contains("gzip"))
                responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
            else if (webResponse.ContentEncoding.ToLower().Contains("deflate"))
                responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);

            if (responseStream != null) webImage = Image.FromStream(responseStream);
            tcs.TrySetResult(webImage);
            webResponse.Close();
            responseStream.Close();
        });
    return tcs.Task.Result;
}
Run Code Online (Sandbox Code Playgroud)

这是调用上述解决方案的方法:

PictureBox img = new System.Windows.Forms.PictureBox();
var result = GetImageAsync(ThumbnailUrl);
result.ContinueWith(task =>
{
    img.Image = task.Result;
});
Run Code Online (Sandbox Code Playgroud)