首页 新闻 会员 周边 捐助

C#多线程循环DataTable

0
悬赏园豆:10 [已解决问题] 解决于 2016-05-06 09:10
for (int a = 0; a < dts.Rows.Count; a++)
                {
                    DataRow row = dts.Rows[a];

                    trd = new Thread(new ParameterizedThreadStart(ResultOut));
                   
                    trd.IsBackground = true;
                    trd.Start(row);

                    if (trd.ThreadState == System.Threading.ThreadState.Aborted || trd.ThreadState == System.Threading.ThreadState.Stopped)
                    {
                        trd.IsBackground = true;
                        trd.Start(dts.Rows[a]);
                    }
                 
                }



        public void ResultOut(object row)
        {

            DataRow r = (DataRow)row;
            {
               
                    if (!lvDataInDBInfo.InvokeRequired)
                    {


                        try
                        {

                            AreaCode = r["AreaCode"].ToString();
                            string server = r["SSIPAddess"].ToString();
                            string uid = r["SSLoginName"].ToString();
                            string pwd = r["SSLoginPwd"].ToString();
                            SStationName = r["SStationName"].ToString();
                            sqlconn = "server=" + server + ";database=EnvDataCity;uid=" + uid + ";pwd=" + pwd;
                            for (int i = 1; i <= 1; i++)
                            {
                                //if (AreaCode != "SS4301")
                                {
                                    queryDate = Convert.ToDateTime(DateTime.Now.AddDays(-i).ToString("yyyy-MM-dd"));
                                    try
                                    {
                                        ZdHours(AreaCode, sqlconn);

                                        {

                                            dsDailyRpt = DbaseCS.ExecuteDataSet("up_GetNewDailyRpt", new SqlParameter[] { new SqlParameter("@queryDate", queryDate), new SqlParameter("@areaCode", AreaCode) }, CmdType.StoreProcedure);

                                            if (dsDailyRpt.Tables[0].Rows.Count > 0)
                                            {
                                                dsDailyRpt.Tables[0].Rows.Clear();

                                            }
                                            NewRptUtil.GetDailyRptViewTable(dsDailyRpt, SStationName, AreaCode.Substring(2, 4) + "00", ref dsValues, queryDate);

                                            SaveDataToCity();
                                            r["IsUpdated"] = true;
                                            // SaveDataToProvince();
                                            // AduitNewHourReport();
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        // lvDataInDBInfo.Items.Add("数据自动入库失败");

                                    }
                                }

                            }

                        }


                        catch (Exception ex)
                        {
                            lvDataInDBInfo.Items.Add(ex.Message);
                        }





                    }
                    else
                    {
                        Synchronization tmpDel = new Synchronization(ResultOut);
                        this.Invoke(tmpDel, row);
                    }


                }
            
        }
上面的DataTable就是图上的dts.感觉没有多线程的效果。并且还掉数据。怎么完整的实现多线程,循环每个地区城市???

 

 
转角VV的主页 转角VV | 初学一级 | 园豆:163
提问于:2016-03-22 17:15
< >
分享
最佳答案
0

你最后大量的操作都丢到ui线程上去了

if (!lvDataInDBInfo.InvokeRequired) {....

这里是ui线程在处理中,所以你的感觉很正确。

抛开你的问题,你的代码实现有相当多的问题。

1.在循环中依次去操作db这个基本是不可取的,数据量大了你这玩意就算实现的是正确的估计也没办法用

2.你线程使用的姿势不对,完全无法看懂

if (trd.ThreadState == System.Threading.ThreadState.Aborted || trd.ThreadState == System.Threading.ThreadState.Stopped)

这个判断到底要干嘛

针对这种场景一般都是用线程池,否则就算你线程足够你这样跑光线程切换就是要死人的

 

 

收获园豆:10
Daniel Cai | 专家六级 |园豆:10424 | 2016-03-22 18:43

是的,循环连接每个城市去取数据,进行处理。数据量有点大。肯定要使用多线程。但是多线程以前没有涉及到过。具体怎么使用,能给个详细的参考吗?

转角VV | 园豆:163 (初学一级) | 2016-03-23 13:43

@转角VV: 你用的framework版本多少?

Daniel Cai | 园豆:10424 (专家六级) | 2016-03-23 14:10

@Daniel Cai: 4.0。

转角VV | 园豆:163 (初学一级) | 2016-03-23 14:25

@转角VV: 一般针对你这种场景就直接用线程池了。

for(int i=0;i<100;i++)

{

  var target=i;

  ThreadPool.QueueUserWorkItem(_=>{

    //your logic here...

           Console.WriteLine(target);

       },null);

}

如果你需要在处理一部分就反馈到ui上就类似你上面的实现,但你写反了。

正常的应该是

void RefreshUI(string message)

{

   if(control.IsInvokeRequired)

  {

     //this runs in a non ui thread.

  Action<string> yourMethodDelegate=RefreshUI;

     yourControl.Invoke(yourMethodDelegate,message);  

  }

else

{

 //this runs in ui thread.

  yourControl.Text=message;

 }

 

}

Daniel Cai | 园豆:10424 (专家六级) | 2016-03-23 14:41

@转角VV: 你是期望当ui上给了一个命令后,你在后台拉取一坨数据,处理完毕后更新到db中,然后ui上显式个成功或者失败么?

Daniel Cai | 园豆:10424 (专家六级) | 2016-03-23 14:45

@Daniel Cai: ,.嗯嗯是的

转角VV | 园豆:163 (初学一级) | 2016-03-23 15:01

@转角VV: 如果是4.0,你可以用task和cancellationtokensource一起配合完成你的场景,使用起来会简单些(控制什么时候停止),当然你也可以直接通过直接控制线程来操作,只是稍微麻烦点。

根据你的需求,就是在上面我给出的给threadpool的方法的委托方法中进行输出的处理。

ThreadPool.QueueUserWorkItem(_=>{

    //your logic here

    RefreshUI(isSuccess?"成功":"失败"); 

       },null);

Daniel Cai | 园豆:10424 (专家六级) | 2016-03-23 15:15
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册