NEWS

技术文章

ASP.net:在多线程操作数据库

编辑:
起点网络
发布时间:
2017-6-7
点击:
在查询大数据量时,窗体界面会不动,“正在查询...”的提示也不能显示。所以打算用多线程来实现,可是当在线程里面执行到 this.dataGridDF.DataSource=dt.DefaultView;填充数据时却提示报错,说什么该线程不能调用主线程创建的控件等等。
  后来查了许多资料,终于搞定。可以在查询数据库时操作别的了,“正在查询...”的提示也显示了。
  //或者在前面用一个线程查询,在线程里调用dataGrid.BeginInvoke(异步方法)来单独填充
 
 
public delegate void myDelegate(); 
DataTable dt; 
 
private void btnDianJia_Click(object sender, System.EventArgs e) 
 try 
 { 
  mythread = new Thread(new ThreadStart(ThreadWork)); 
  mythread.Start();     
 } 
 catch(System.Exception ex) 
 { 
  MessageBox.Show(this,ex.Message,"提示",MessageBoxButtons.OK,MessageBoxIcon.Information); 
 }    
 
void ThreadWork() 
 this.dataGridDJ.CaptionText="正在查询电价数据..."; 
 mf.statusBarPanel1.Text="正在查询电价数据..."; 
 this.Cursor=Cursors.WaitCursor; 
 
 
 string shijian=this.dateTimeDianJia.DateValue; 
 DateTime today=DateTime.Today; 
 string mingcheng=this.txtMingCheng.Text; 
 string leibie=this.cmbBoxLiebie_DJ.SelectedValue.ToString(); 
 PowerWeb.BLL.DianFeiDianJia.DianJia dj=new PowerWeb.BLL.DianFeiDianJia.DianJia(); 
 
 if(shijian==today.ToString("yyyyMM")) 
 { 
  dt=dj.GetList(leibie,mingcheng).Tables[0]; 
 } 
 else 
 { 
  dt=dj.GetListOld(leibie,mingcheng,shijian).Tables[0]; 
 } 
 this.dataGridDJ.CaptionText=shijian+"电价信息 (共计条"+dt.Rows.Count.ToString()+"记录)"; 
 
 dataGridDJ.BeginInvoke(new myDelegate(FillData));//异步调用(来填充) 
  
 this.Cursor=Cursors.Default; 
 mf.statusBarPanel1.Text="查询结束"; 
 
private void FillData() 
 this.dataGridDJ.DataSource=dt.DefaultView; 

另附网上另一个实例供大家: 

using System;
using System.Collections;
using System.Data;
using System.Threading;

namespace InfoGather
{


    #region 价格操作类

    /// <summary> 
    /// 价格类的方法说明 
    /// ThreadsStart 
    /// Number 
    /// CatchPrice 
    /// InsertPrice 
    /// RunPriceAll 
    /// RunPriceBySiteName 
    /// RunPriceBySiteNameGameName 
    /// RunPriceBySiteNameGameNameServerName 
    /// </summary> 
    public class PriceOperate
    {
        private const int ThNum = 30;
        private Thread[] arrThreads = new Thread[ThNum];
        private Thread MainThread;
        private DataTable ConfigPriceDt = new DataTable();
        private DataTable PriceDt = new DataTable();
        private ArrayList arrNums = new ArrayList();
        private ReaderWriterLock PriceDtLock = new ReaderWriterLock();
        private ReaderWriterLock ConfigPriceDtLock = new ReaderWriterLock();
        //定义一个公共表 

        public PriceOperate()
        {
            InitTable();
        }

        /// <summary> 
        /// 初始化表函数 
        /// </summary> 
        private void InitTable()
        {
            PriceDt.Columns.Add("sitename");
            PriceDt.Columns.Add("gamename");
            PriceDt.Columns.Add("servername");
            PriceDt.Columns.Add("num");
            PriceDt.Columns.Add("unit");
            PriceDt.Columns.Add("price");
            PriceDt.Columns.Add("avgprice");
            PriceDt.Columns.Add("url");
        }

        private void ThreadEnd()
        {
            //线程结束,更新所有数据 

            SqlInsert.Insert("Data Source=.;Initial Catalog=IG911;uid=sa;pwd=ok;integrated security=true",
                             "insert into tempprice (sitename,gamename,servername,num,unit,price,avgprice,url)values(@sitename,@gamename,@servername,@num,@unit,@price,@avgprice,@url)",
                             PriceDt);
        }

        private void PriceDtAdd(DataRow dr)
        {
            PriceDtLock.AcquireWriterLock(100);
            PriceDt.Rows.Add(dr);
            PriceDtLock.ReleaseWriterLock();
        }

        private void ConfigPriceUpdate(int index, bool state)
        {
            ConfigPriceDtLock.AcquireWriterLock(20);
            ConfigPriceDt.Rows[index]["isupdate"] = state;
            ConfigPriceDtLock.ReleaseWriterLock();
        }

        /// <summary> 
        /// index  configprice表的 映射 
        /// </summary> 
        /// <param name="v_Index"> </param> 
        /// 
        //  /// <summary> 
        ///// 外界的参数  CatchPrice InsertPrice          arrNumsTotal  arrThreads    ConfigPriceDt        NUM 
        ///// </summary> 
        //private void CatchPrice()//RunPriceAll()[完成配置表的装配工作]->ThreadsStart()【完成arrnum】->CatchPrice()[完成线程的启动工作]->Insert() 
        //{ 
        //    while (true) 
        //    { 
        //        Thread.Sleep(10); 
        //        try 
        //        { 
        //            if (arrNumsTotal.Count > 0)//控制全体数量通常是32000个,很多的  
        //            { 
        //                for (int i = 0; i < NUM; i++)//控制线程数量,只有30个左右 
        //                { 
        //                    if (arrThreads[i] == null||!arrThreads[i].IsAlive) 
        //                    {                          
        //                        object obj = arrNumsTotal[0]; 
        //                        arrNumsTotal.RemoveAt(0); 
        //                        arrThreads[i] = new Thread(new ParameterizedThreadStart(InsertPrice));      
        //                        arrThreads[i].Start(obj); 
        //                    }                        
        //                } 
        //            } 
        //            else//批量更新到数据库中去 

        public void InsertPrice(object v_Index)
        {
            ConfigPrice cprice = new ConfigPrice();
            TempPrice tprice = new TempPrice();
            PriceValues priceValues = new PriceValues();
            PriceGet priceGet = new PriceGet();

            int index = Convert.ToInt32(v_Index);
            string url = ConfigPriceDt.Rows[index]["url"].ToString();
            priceGet.SetConfig(ConfigPriceDt.Rows[index]["url"].ToString(),
                               ConfigPriceDt.Rows[index]["beginword"].ToString(),
                               ConfigPriceDt.Rows[index]["endword"].ToString(),
                               ConfigPriceDt.Rows[index]["regular"].ToString());
            priceGet.GetValue(ref priceValues);
            if (priceValues.Count > 0)
            {
                for (int i = 0; i < priceValues.Count; i++)
                {
//将数据先放入到内存表中; 
                    DataRow dr = PriceDt.NewRow();
                    dr["sitename"] = ConfigPriceDt.Rows[index]["sitename"].ToString();
                    dr["gamename"] = ConfigPriceDt.Rows[index]["gamename"].ToString();
                    dr["servername"] = ConfigPriceDt.Rows[index]["Servername"].ToString();
                    dr["num"] = priceValues.Number[i];
                    dr["unit"] = priceValues.Unit[i].ToString();
                    dr["price"] = priceValues.Price[i].ToString();
                    dr["avgprice"] =
                        Math.Round(
                            Convert.ToDouble(priceValues.Price[i].ToString())/Convert.ToDouble(priceValues.Number[i]), 2);
                    dr["url"] = ConfigPriceDt.Rows[index]["Url"].ToString();
                    PriceDtAdd(dr);
                }
                ConfigPriceUpdate(index, true);
            }
            else
            {
                ConfigPriceUpdate(index, false);
            }
            //刘经理写的在访问后停顿三秒钟,防止过频访问对方封ip地址 
            Thread.Sleep(3000);
        }


        public void RunPriceAll()
        {
            ConfigPrice cprice = new ConfigPrice();
            ConfigPriceDt = cprice.SelectAll().Tables[0];
            ThreadsStart();
        }


        protected void ThreadsStart()
        {
            for (int i = 0; i < ConfigPriceDt.Rows.Count; i++)
            {
                arrNums.Add(i);
            }

            MainThread = new Thread(new ThreadStart(CatchPrice));
            MainThread.Start();
        }

        private void CatchPrice()
        {
            while (true)
            {
                Thread.Sleep(10);
                try
                {
                    if (arrNums.Count > 0)
                    {
                        for (int i = 0; i < ThNum; i++)
                        {
                            if (arrThreads[i] == null || !arrThreads[i].IsAlive)
                            {
//刘经理的改进方案,让其随机访问,不单访问同一个网站 
                                int num = Number(arrNums.Count);
                                object obj = arrNums[num];
                                arrNums.RemoveAt(num);
                                arrThreads[i] = new Thread(new ParameterizedThreadStart(InsertPrice));
                                arrThreads[i].Priority = ThreadPriority.BelowNormal;
                                arrThreads[i].Start(obj);
                            }
                        }
                    }
                    else
                    {
                        bool res = true;
                        for (int i = 0; i < ThNum; i++)
                        {
                            if (arrThreads[i].IsAlive)
                            {
                                res = false;
                            }
                        }
                        if (res)
                        {
                            ThreadEnd();
                            break;
                        }
                    }
                }
                catch
                {
                    continue;
                }
            }
        }

    }

    #endregion
}
标签  编程技术 C#
相关文章

Copyright@宁波起点网络. All rights reserved. Powered by 起点网络       备案号:浙ICP备 16017710号