c# - GetResponseAsync png 链接 url - 参数无效
问题描述
我必须编写一个从 url 打印 png 的 Windows 窗体应用程序,我想异步编写代码。这是我的工作代码(同步)
public Bitmap GetImage()
{
Bitmap bmp;
var request = WebRequest.Create("http://www.basilicasanmarco.it/wp-content/themes/tema-basilicasmarco/library/images/patriarcato.png");
using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
{
bmp = new Bitmap(stream);
}
return bmp;
}
private void PrintImage(PaintEventArgs e)
{
using (var imag = GetImage())
{
if (imag == null)
return;
var newHeight = mainImage.Height;
var rapporto = newHeight / (double) imag.Height;
var newWidth = Convert.ToInt32(rapporto * imag.Width);
var imageLocationX = Convert.ToInt32((mainImage.Width - newWidth) / 2.0);
e.Graphics.DrawImage(imag, imageLocationX, 0, newWidth, newHeight);
}
}
现在我想以异步等待方式编写相同的代码,这是我的片段:
public async Task<Bitmap> GetImage()
{
Bitmap bmp;
var request = WebRequest.Create("http://www.basilicasanmarco.it/wp-content/themes/tema-basilicasmarco/library/images/patriarcato.png");
using (var response = await request.GetResponseAsync())
using (var stream = response.GetResponseStream())
{
bmp = new Bitmap(stream);
}
return bmp;
}
private async Task PrintImageAsync(PaintEventArgs e)
{
using (var imag = await GetImage())
{
var newHeight = mainImage.Height;
var rapporto = newHeight / (double) imag.Height;
var newWidth = Convert.ToInt32(rapporto * imag.Width);
var imageLocationX = Convert.ToInt32((mainImage.Width - newWidth) / 2.0);
e.Graphics.DrawImage(imag, imageLocationX, 0, newWidth, newHeight);
}
}
第一个同步代码运行良好,当我转向异步部分时,我在
e.Graphics.DrawImage(imag, imageLocationX, 0, newWidth, newHeight);
代码。获得的位图似乎没问题,它有正确的宽度和高度,但里面有问题,只有在异步方法中。
我究竟做错了什么?
更新:我通过以下方式等待Paint
a 方法中的方法Panel
:
this.panel.Paint += new System.Windows.Forms.PaintEventHandler(this.mainImage_Paint);
private async void mainImage_Paint(object sender, PaintEventArgs e)
{
await PrintImageAsync(e);
}
我想要获得的是在 Panel 而不是 PictureBox 中绘制下载的图像,因为我需要更底层的方法。
解决方案
每次重新绘制控件时都会调用 Paint 事件处理程序,并且您可能不希望每次发生这种情况时都下载图像。
调用事件处理程序时,似乎访问事件 args (e) 参数中的图形对象在异步操作之前成功,但在等待之后失败。
所以;
目前尚不清楚是什么触发了源代码中图像的下载,但如果尝试异步执行,请异步获取图像并将其保存在字段中,如果可用,将其绘制在面板上。
下面假设你直接下载图片,没有任何用户操作,这个地方就是async void Form_Load():(你可以看到图片是在后台下载的!)
private async void Form1_Load(object sender, EventArgs e)
{
this.panel1.Paint += this.mainImage_Paint;
downloadedBitmap = await GetImage();
// When we got the image, invalidate the panel to trigger a re-paint
this.panel1.Invalidate();
}
// Keep the downloaded image in a field:
private Image downloadedBitmap;
private async void mainImage_Paint(object sender, PaintEventArgs e)
{
if (downloadedBitmap != null)
{
var newHeight = mainImage.Height;
var rapporto = newHeight / (double)downloadedBitmap.Height;
var newWidth = Convert.ToInt32(rapporto * downloadedBitmap.Width);
var imageLocationX = Convert.ToInt32((mainImage.Width - newWidth) / 2.0);
e.Graphics.DrawImage(downloadedBitmap, imageLocationX, 0, newWidth, newHeight);
}
}