我做了个异步下载AP,为保证同时有2个线程下载,做了线程延时,直接用thread.spleep会阻塞异步。如果到达2同时下载个就等待,值得检查到系统有1个或者0个的时候再次继续
队列中有1,2,3,4。下载完ID:1,2的,延时判断CheckOutOfMaxThread()通过再次运行,又从1开始了,为啥不从上次延时的3开始那?调用代码如下
                        for (int i = 0; i < count_total;i++ )
                        {
                            pic_id = ApplicationCommon.IsInt(dt_gallery.Rows[i]["pic_id"].ToString());
                            pic_no = dt_gallery.Rows[i]["pic_no"].ToString();
                            user_account = dt_gallery.Rows[i]["user_account"].ToString();
                            if (CheckOutOfMaxThread())
                            {
                            #region  Gallery download                                                 #endregion
                            }
}
        /// <summary>
        /// if out of max thread then sleep 1 minute then check again
        /// </summary>
        /// <returns></returns>
        private bool CheckOutOfMaxThread()
        {
            bool flag_run = false;
            int current_count = 0;
            current_count = ApplicationCommon.IsInt(lb_download_count.Text);
            if (current_count >= MaxThread)
            {
                writeInfo(current_count + " out of " + MaxThread + " thread ,then sleep 1 minute then to run", Color.Red);
                delayTime(60); //sleep 1 minute
                CheckOutOfMaxThread();
            }
            else
            {
                flag_run = true;
            }
            flag_run = true; 
            return flag_run;
        }
C#多线程下载线程

解决方案 »

  1.   

    下载完ID:1,2的,那你就应该把下载的ID记下来
    问题描述得不太清楚,白白sleep一分钟就是为了查询线程数量?
      

  2.   


    是呀,Sleep 1分钟查询现在正在下载的数目。如你所说这时我再次去查询一次DB中这条记录状态或者记录下已投入下载的ID。但是这样效率有所降低,能不能让线程在上次暂停的地方继续从3,而不是从1开始那?有啥好办法吗?
      

  3.   

    是的,主要细节如下:       public void work()
            {
                //////////////////////////////////////////////////////////////////////////
                //initial value
                button1.Enabled = false;
                //timer1.Enabled = false;
                progressBar1.Value = 0;            string str_url = "";
                string str_referer = "";
                string str_host = "";
                string postData = "";            string valid_code = "";
                string session_id = "";            string str_key = "";
                string str_value = "";            //////////////////////////////////////////////////////////////////////////////
                ////clean the rich textbox
                string content = richTextBox1.Text;
                //if (content.Length > 10000)
                if (content.Length > 5000)
                {
                    richTextBox1.Text = "";
                }
                //////////////////////////////////////////////////////////////////////////            MaxThread = gallery_db.MaxThread;   //get max thread download in the same time            writeInfo("Start to run", Color.Blue);
                try
                {                //////////////////////////////////////////////////////////////////////////
                    //get db data
                    //////////////////////////////////////////////////////////////////////////
                    DataTable dt_gallery = gallery_db.GetTablePicture();
                    int count_total=dt_gallery.Rows.Count;                lb_queue_count.Text =count_total.ToString();
                    progressBar1.Maximum = count_total;                if (count_total>0)
                    {
                                            if (responseData.IndexOf("asusimage")!=-1)
                        {
                            writeInfo("Ok", Color.Green);                        for (int i = 0; i < count_total;i++ )
                            {
                                pic_id = ApplicationCommon.IsInt(dt_gallery.Rows[i]["pic_id"].ToString());
                                pic_no = dt_gallery.Rows[i]["pic_no"].ToString();
                                user_account = dt_gallery.Rows[i]["user_account"].ToString();
                                if (CheckOutOfMaxThread()) //延时轮询检查下载数目,满足条件后,他又从头开始,而不是从延时断点开始
                                {
                                #region  Gallery download   #region  use async download                              string user_token = ""; //pic_id+pic_no+pic_file_name+user_account
                                  user_token = pic_id + "*" + pic_no + "*" + pic_file_name + "*" + user_account;
                                  DownloadFile(str_url, gallery_db.SavePath + pic_file_name, user_token); #endregion
                                #endregion
                                }
                            }
                    }            }
                catch (System.Exception ex)
                {
                    LogFunction.WriteErrorLog(ex.ToString());
                }
                finally
                {                writeInfo("Finish to run", Color.Blue);                if (CheckThreadRunning())
                    {
                        button1.Enabled = true;
                        //timer1.Enabled = true;
                    }            }
      
            }       /// <summary>
            /// if out of max thread then sleep 1 minute then check again
            /// </summary>
            /// <returns></returns>
            private bool CheckOutOfMaxThread()
            {
                bool flag_run = false;
                int current_count = 0;
                current_count = ApplicationCommon.IsInt(lb_download_count.Text);
                if (current_count >= MaxThread)
                {
                    writeInfo(current_count + " out of " + MaxThread + " thread ,then sleep 1 minute then to run", Color.Red);
                    delayTime(60); //sleep 1 minute
                    CheckOutOfMaxThread();
                }
                else
                {
                    flag_run = true;
                }
                flag_run = true; 
                return flag_run;
            }
    感觉问题主要在我写的方法问题,有啥好办法吗
    CheckOutOfMaxThread() //延时轮询检查下载数目,满足条件后,他又从头开始,而不是从延时断点开始
      

  4.   

    忘了补充delayTime()方法        private void delayTime(double secend)
            {
                DateTime tempTime = DateTime.Now;
                while (tempTime.AddSeconds(secend).CompareTo(DateTime.Now) > 0)
                    Application.DoEvents();
            }
      

  5.   

    其实是你的思路有问题
    你是可以确定dt_gallery.Rows.Count的
    根据这个,一开始你就可以先开两个线程,每个线程处理的机制相同
    1.线程开始处理时,先将处理的Row数据对象标记正在处理..
    2.处理完之后,标记为处理完毕
    3.遍历Rows,取得第一个还未处理的Row,转到步骤1. 如果所有的都已处理完毕,则返回(线程结束)这样就不必去判断线程的数量了