GetResponseAsyn c png URL ссылки - параметр недействителен - PullRequest
1 голос
/ 11 апреля 2020

Мне нужно написать приложение Windows Form, которое печатает png из URL, я хотел бы написать код асинхронно. Вот мой рабочий код (syn c)

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);
    }
}

Теперь я хотел бы написать тот же код в асинхронном режиме c в ожидании, вот мой фрагмент:

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);
    }
}

Первый синхронный код работает хорошо, когда я обращаюсь к асиновой части c, у меня появляется исключение «Параметр не действителен» (исключение System.Drawing) в

e.Graphics.DrawImage(imag, imageLocationX, 0, newWidth, newHeight);

код. Полученное растровое изображение выглядит нормально, оно имеет правильные ширину и высоту, но внутри что-то не так, только в асинхронном методе.

Что я делаю не так?

Обновление : Я жду метод в Paint методе 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, потому что Мне нужен более низкоуровневый подход.

1 Ответ

2 голосов
/ 11 апреля 2020

Обработчик события Paint вызывается для каждого повторного рисования элемента управления, и вы, вероятно, не хотите загружать изображение каждый раз, когда это происходит.

Когда вызывается обработчик события, это похоже на доступ графический объект в параметре event args (e) завершается успешно ДО операции asyn c, но не завершается после ожидания.

Следовательно;

Непонятно, что вызывает загрузку изображения в исходном коде, но если вы пытаетесь сделать это асинхронно c, получите изображение асинхронно и сохраните его в поле и нарисуйте его на панели, если оно доступно.

В следующем предполагается, что вы загружаете изображение напрямую, без каких-либо действий пользователя, и место для этого asyn c 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);
    }
}
...