none
winform下关于datagridview多线程显示图片的问题 RRS feed

  • 问题

  • 数据库中存储了图片的网络地址,我是这么处理的:

     

    for (int i = 0; i < dgvList.Rows.Count; i++)
     {
     Image img = Image.FromStream(WebRequest.Create(dgvList.Rows[i].Cells[14].Value.ToString()).GetResponse().GetResponseStream());
     dgvList.Rows[i].Cells[0].Value = img;
     }
    

     

    发现解析的速度很慢,把它改成多线程解析:

     

    for (int i = 0; i < dgvList.Rows.Count; i++)
     {
     
     td = new Thread(getimage);
     td.Name = i.ToString();
    td.Start();
     }
     
    
    
     Thread td;
        private void getimage()
        {
          Image img = Image.FromStream(WebRequest.Create(dgvList.Rows[Convert.ToInt32(td.Name.ToString())].Cells[14].Value.ToString()).GetResponse().GetResponseStream());
          dgvList.Rows[Convert.ToInt32(td.Name.ToString())].Cells[0].Value = img;
        }
    
    图片根本就不显示了,求助各位大大,看看怎么回事,发现图片都在gridview中的最后一行显示,貌似i的值只传了最后一个

     




    2011年4月12日 2:31

答案

  • 你可能还需要在下载过程中进行异常处理,我把上面的代码完善了下。

    /// <summary>
    /// 开始下载图片
    /// </summary>
    /// <param name="threadCount">启动的线程数</param>
    void BeginDownloadImage(int threadCount)
    {
      var threads = new List<BackgroundWorker>();
    
      for (int i = 0; i < threadCount; i++)
      {
        BackgroundWorker bg = new BackgroundWorker();
        bg.DoWork += (o, e) =>
        {
          var row = GetWorkingRow();
          while (row != null)
          {
            int errorCount = 0;
            // 简单异常处理,超过 10 次下载不成功则放弃
            while (true)
            {
              try
              {
                row["ImageContext"] = Image.FromStream(WebRequest.Create(row["ImageUrl"].ToString()).GetResponse().GetResponseStream()); ;
                break;
              }
              catch (Exception ex)
              {
                // save log
                errorCount++;
                System.Threading.Thread.Sleep(6000);
                if (errorCount >= 10)
                  break;
              }
            }
    
            row = GetWorkingRow();
          }
        };
    
        threads.Add(bg);
      }
    
      foreach (var bg in threads)
        bg.RunWorkerAsync();
    }
    


    知识改变命运,奋斗成就人生!
    2011年4月12日 5:21
    版主

全部回复

  • 是不是线程未启动。
    胡超
    2011年4月12日 3:22
  • 线程启动了,发现有几个图片可以获取,有的就不行
    2011年4月12日 3:43
  • 你好!

    我写了个示例演示了同时使用多个线程下载图片,使用到了 BackgroundWorker 控件,请参考:

    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Net;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
      public partial class Form1 : Form
      {
        public Form1()
        {
          InitializeComponent();
          Initialize();
          BeginDownloadImage(5);
        }
    
        static object locker = new object();
        int currentRowIndex = -1;
        DataTable dt;
        DataGridView dgv;
    
        private void Initialize()
        {
          dt = new DataTable();
          dt.Columns.Add("Id", typeof(int));
          dt.Columns.Add("ImageUrl");
          dt.Columns.Add("ImageContext", typeof(Image));
    
          var testUrl = "http://i4.social.microsoft.com/Profile/u/avatar.jpg?displayName=%E8%82%96%E5%B0%8F%E5%8B%87&size=extralarge&version=b759daaa-17ab-4a47-89b8-9481b21a03ee";
          for (int i = 0; i < 100; i++)
          {
            dt.Rows.Add(new object[] { i, testUrl, null });
          }
    
          dgv = new DataGridView();
          dgv.Dock = DockStyle.Fill;
          dgv.DataSource = new BindingSource(dt, null);
    
          this.Controls.Add(dgv);
        }
    
        /// <summary>
        /// 获取当前需要下载图片的 DataRow
        /// </summary>
        /// <returns></returns>
        DataRow GetWorkingRow()
        {
          lock (locker)
          {
            var filter = string.Format( "ImageContext is null and Id > {0}", currentRowIndex);
            var sort = "Id";
            foreach (var row in this.dt.Select(filter, sort))
            {
              currentRowIndex++;
              return row;
            }
    
            return null;
          }
        }
    
        /// <summary>
        /// 开始下载图片
        /// </summary>
        /// <param name="threadCount">启动的线程数</param>
        void BeginDownloadImage(int threadCount)
        {
          var threads = new List<BackgroundWorker>();
    
          for (int i = 0; i < threadCount; i++)
          {
            BackgroundWorker bg = new BackgroundWorker();
            bg.DoWork += (o, e) =>
            {
              var row = GetWorkingRow();
              while (row != null)
              {
                row["ImageContext"] = Image.FromStream(WebRequest.Create(row["ImageUrl"].ToString()).GetResponse().GetResponseStream()); ;
                row = GetWorkingRow();
              }
            };
    
            threads.Add(bg);
          }
    
          foreach (var bg in threads)
            bg.RunWorkerAsync();
        }
      }
    }
    


    知识改变命运,奋斗成就人生!
    2011年4月12日 5:15
    版主
  • 你可能还需要在下载过程中进行异常处理,我把上面的代码完善了下。

    /// <summary>
    /// 开始下载图片
    /// </summary>
    /// <param name="threadCount">启动的线程数</param>
    void BeginDownloadImage(int threadCount)
    {
      var threads = new List<BackgroundWorker>();
    
      for (int i = 0; i < threadCount; i++)
      {
        BackgroundWorker bg = new BackgroundWorker();
        bg.DoWork += (o, e) =>
        {
          var row = GetWorkingRow();
          while (row != null)
          {
            int errorCount = 0;
            // 简单异常处理,超过 10 次下载不成功则放弃
            while (true)
            {
              try
              {
                row["ImageContext"] = Image.FromStream(WebRequest.Create(row["ImageUrl"].ToString()).GetResponse().GetResponseStream()); ;
                break;
              }
              catch (Exception ex)
              {
                // save log
                errorCount++;
                System.Threading.Thread.Sleep(6000);
                if (errorCount >= 10)
                  break;
              }
            }
    
            row = GetWorkingRow();
          }
        };
    
        threads.Add(bg);
      }
    
      foreach (var bg in threads)
        bg.RunWorkerAsync();
    }
    


    知识改变命运,奋斗成就人生!
    2011年4月12日 5:21
    版主
  • 谢谢版主肖小勇的帮助,感谢
    2011年4月12日 6:37