【问题标题】:Multi threading in C# while downloading an image from the internet从 Internet 下载图像时 C# 中的多线程
【发布时间】:2011-07-15 02:53:47
【问题描述】:

我有一个从互联网加载图像的功能。然而,当它正在加载时,我的应用程序不能做任何其他事情。有没有办法解决这个问题?

谢谢!

这是我的代码:

public static Bitmap BitmapFromWeb(string URL)
{
    try
    {
        HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(URL);
        myRequest.Method = "GET";
        HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
        Bitmap bmp = new Bitmap(myResponse.GetResponseStream());
        myResponse.Close();
        return bmp;
    }
    catch (Exception ex)
    {
        return null;
    }
}


private void button1_Click(object sender, EventArgs e)
{
    load_avatrar();
}


private void load_avatrar()
{
    pictureBox_avatar.Image = BitmapFromWeb(avatral_url);
}

【问题讨论】:

  • 您可以在不同的线程上下载图像,这样应用程序不会同时卡住。请提供一些代码和更多信息

标签: c# multithreading


【解决方案1】:

使用后台工作者绝对是一个解决方案。但是,WebRequest 类支持异步调用。它还将通过使用 IO 端口提供更好的性能。

How to use HttpWebRequest (.NET) asynchronously?

【讨论】:

    【解决方案2】:

    HttpWebRequest 类对此提供支持。您可以使用BeginGetRequest 方法代替GetRequest 来进行异步调用。

    public static void BitmapFromWeb(string URL, Action<Bitmap> useBitmap) {
      try {
        HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(URL);
        myRequest.Method = "GET";
        myRequest.BeginGetResponse(ar => {
          HttpWebResponse response = (HttpWebResponse) myRequest.EndGetResponse(ar);
          Bitmap bmp = new Bitmap(response.GetResponseStream());
          myResponse.Close();
          useBitmap(bmp);
        });
      } catch (Exception ex) {
        return;
      }
    }
    
    private void button1_Click(object sender, EventArgs e) {
      load_avatrar();
    }
    
    private void load_avatrar() {
      BitmapFromWeb(avatral_url, b => pictureBox_avatar.Image = b);
    }
    

    【讨论】:

      【解决方案3】:

      假设 WinForms,您可以简单地将图片框指向源:

      pictureBox_avatar.ImageLocation  = URL;
      

      没有其他需要。

      处理 LoadCompleted 事件以检测错误。

      【讨论】:

        【解决方案4】:

        看看BackgroundWorker。这意味着在另一个线程中运行这些类型的操作以释放您的应用程序。

        更新

        根据您的代码,您可以使用 BackgroundWorker 获得类似这样的内容:

        private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs args)
        {
            Bitmap b = BitmapFromWeb("some string");
            this.Invoke((MethodInvoker)SOME_METHOD_USING_BITMAP(b));
        }
        

        当位图下载完成后,SOME_METHOD_USING_BITMAP 将被调用,结果你可以相应地更新你的 UI。

        更新 2

        SOME_METHOD_USING_BITMAP 将是您的 load_avatar 方法。让它接受Bitmap 类型的参数:

        private void load_avatar(Bitmap avatar)
        {
            pictureBox_avatar.Image = avatar;
        }
        

        【讨论】:

        • 谢谢!嗯......奇怪的是它说“错误2无法将类型'void'转换为'System.Windows.Forms.MethodInvoker' C:\Users\Robert\documents\visual studio 2010\Projects\XMPP\main\Form1.cs 74 26 main " on this.Invoke( (MethodInvoker) load_avatrar(b) );
        • 我的错。使用匿名方法会更容易:this.Invoke((MethodInvoker)delegate { load_avatar(b); });
        【解决方案5】:

        您可以使用 BackgroundWorker 类来异步下载图像。 这是msdn页面的link 这是好的tutorial

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-07
          • 2015-12-31
          • 1970-01-01
          • 2015-10-01
          • 2023-04-11
          • 2011-08-09
          相关资源
          最近更新 更多