首页 新闻 会员 周边 捐助

线程池问题,跑数据跑了一些之后就不执行了、请大侠赐教

0
悬赏园豆:30 [已解决问题] 解决于 2013-02-19 17:00

循环请求接口A获得A的数据后线程池添加A入库,同时线程池添加B和C,(将A作为条件提供给接口B和C发起请求),获得返回信息入库,

我用了,ManualResetEvent和AutoResetEvent,当A执行时候使B和C等待WaitOne(),B和C中都是循环请求的,B和C循环执行后设置信号,B设置 autoEvents[0].Set();C设置 autoEvents[1].Set();

问题是B完全可以执行完成然后执行了autoEvents[0].Set(),而C却没有全部执行完,有时候获取几十条就不动了, 有时候执行上千条也不动,但是根本没执行到autoEvents[1].Set();

不报异常,什么错误都没显示,就是不动了。我看不到线程是否还在运行中(不知道怎么看)。只用VS2010看到调试状态这些线程都是正常、

现在不知道怎么排查原因,为什么B可以正常执行,C却不能、代码有很多,做了精简

View Code
  1     partial class CtripHotelBaseInfoService : ServiceBase
  2     {
  3         private readonly Timer _timer;
  4         //Log.Info("循环下载数据开始--");
  5         private static readonly ILog Log = LogManager.GetLogger("CtripHotelBaseInfoLog");
  6         public CtripHotelBaseInfoService()
  7         {
  8             InitializeComponent();
  9             _timer = new Timer(Settings.Default.TimeSplit * 20 * 1000); //单位为分钟
 10             _timer.Enabled = true;
 11             _timer.Elapsed += SubmitTimerElapsed;
 12         }
 13 
 14         protected override void OnStart(string[] args)
 15         {
 16             // TODO: 在此处添加代码以启动服务。
 17             _timer.Start();
 18             Log.Info("基本信息落地服务已启动....");
 19         }
 20 
 21         protected override void OnStop()
 22         {
 23             // TODO: 在此处添加代码以执行停止服务所需的关闭操作。
 24             _timer.Stop();
 25             Log.Info("基本信息落地服务已停止....");
 26         }
 27 
 28         internal void SubmitTimerElapsed(object sender, ElapsedEventArgs e)
 29         {
 30             _timer.Stop();
 31             try
 32             {
 33                 var serviceClient = new CtripHotelClient("CtripHotelService");
 34                 CtripHotelDataContext context = new CtripHotelDataContext(Settings.Default.CtripHotelConnectionString);
 35                 var cityList = from c in context.Ctrip_Base_City select c;
 36                 int count = cityList.Count();
 37                 Log.InfoFormat("共获取城市信息成功共{0}个", count);
 38                 foreach (var city in cityList)
 39                 {
 40                     Log.InfoFormat("请求接口,城市ID:{0},城市名称:{1} 的信息开始--", city.CityID, city.CityName);
 41 
 42                     string result = serviceClient.OTA_HotelSearchStr(city.CityID.ToString());
 43 
 44                     if (string.IsNullOrEmpty(result))
 45                     {
 46                         return;
 47                     }
 48                     Alpha alpha = new Alpha();
 49                     OTA_HotelSearchRSEntity entity = new OTA_HotelSearchRSEntity();
 50                     entity.head = new HeadEntity();
 51                     #region 解析XML
 52                    
 53                     #endregion
 54                     if (entity != null && entity.head != null && entity.OTA_Hotel != null
 55                         && entity.head.ResultCode.Equals("Success") && entity.head.SubCode.Equals("Success")
 56                         && entity.OTA_Hotel.Count > 0)
 57                     {
 58                         //添加到线程池中区
 59 
 60                         ThreadPool.QueueUserWorkItem(new WaitCallback(alpha.GetGotelBase), entity);
 61                         ThreadPool.QueueUserWorkItem(new WaitCallback(alpha.OTA_HotelDescriptiveInfo), entity.OTA_Hotel);
 62                         ThreadPool.QueueUserWorkItem(new WaitCallback(alpha.OTA_HotelRatePlan), entity.OTA_Hotel);
 63 
 64                         WaitHandle.WaitAll(alpha.autoEvents);
 65                         //GetGotelBase(entity);
 66                         //OTA_HotelDescriptiveInfo(entity.OTA_Hotel);
 67                     }
 68                     else
 69                     {
 70                         // Log.Info(string.Format("<h5 style='color:red;'>请求结束,城市:{0}出错了</h5>,时间:{1}<br>", city.CityName, DateTime.Now));
 71                         Log.InfoFormat("基础信息:ResultCode:{0},ResultMsg:{1},SubCode:{2},SubMsg:{3}", entity.head.ResultCode, entity.head.ResultMsg, entity.head.SubCode, entity.head.SubMsg);
 72                         Log.InfoFormat("城市ID:{0},城市名称:{1} 的信息开始--", city.CityID, city.CityName);
 73                         Log.InfoFormat("返回信息:{0}", result);
 74                     }
 75                     Log.InfoFormat("请求接口,城市ID:{0},城市名称:{1} 的信息结束--", city.CityID, city.CityName);
 76 
 77                 }
 78             }
 79             catch (Exception ex)
 80             {
 81                 Log.InfoFormat("获取城市信息异常:{0},堆栈:{1}", ex.Message, ex);
 82             }
 83             Log.Info("循环下载数据结束--");
 84             _timer.Start();
 85         }
 86 
 87     }
 88 
 89     public class Alpha
 90     {
 91         private static readonly ILog Log = LogManager.GetLogger("CtripHotelBaseInfoLog");
 92         public ManualResetEvent eventX;
 93         public AutoResetEvent[] autoEvents;
 94         public Alpha()
 95         {
 96             autoEvents = new AutoResetEvent[]
 97             {
 98                 new AutoResetEvent(false),
 99                 new AutoResetEvent(false)
100             };
101             eventX = new ManualResetEvent(false);
102         }
103 
104         /// <summary>
105         /// 基本信息入库
106         /// </summary>
107         /// <param name="entity"></param>
108         public void GetGotelBase(object entity)
109         {
110             CtripHotelDataContext context = new CtripHotelDataContext(Settings.Default.CtripHotelConnectionString);
111             Log.Info("存入数据库开始--");
112             context.Connection.Open();
113             DbTransaction tran = context.Connection.BeginTransaction();
114             context.Transaction = tran;
115             try
116             {
117                 OTA_HotelSearchRSEntity en = (OTA_HotelSearchRSEntity)entity;
118                 Ctrip_HotelBase hoteBase = null;
119                 foreach (OTA_HotelEntity hotelEntity in en.OTA_Hotel)
120                 {
121                
122                 }
123                 context.SubmitChanges();
124                 tran.Commit();
125                 Log.Info("存入数据库结束--");
126                 eventX.Set();
127             }
128             catch (Exception ex)
129             {
130                 eventX.Set();
131                 Log.InfoFormat("基础信息入库异常:{0}", ex);
132                 tran.Rollback();
133                 context.Connection.Close();
134                 context.Connection.Dispose();
135             }
136             finally
137             {
138                 context.Connection.Close();
139                 context.Connection.Dispose();
140             }
141         }
142 
143         /// <summary>
144         /// 请求详细信息
145         /// </summary>
146         /// <param name="entity"></param>
147         public void OTA_HotelDescriptiveInfo(object objhotelList)
148         {
149             Log.Info("请求详细信息开始--");
150             try
151             {
152                 eventX.WaitOne();
153                 string ss = string.Empty;
154                 List<OTA_HotelEntity> hotelList = (List<OTA_HotelEntity>)objhotelList;
155                 int pageIndex = 0;
156                 int PageSize = 10;
157                 int pageCount = (int)Math.Ceiling(hotelList.Count / (float)PageSize);
158                 for (pageIndex = 0; pageIndex <= pageCount; pageIndex++)
159                 {
160                     OTA_HotelDescriptiveInfoRQEntity descriptiveInfoRqEntity = new OTA_HotelDescriptiveInfoRQEntity();
161                     descriptiveInfoRqEntity.OTA_HotelDescriptiveInfo = new List<OTA_HotelDescriptiveInfoEntity>();
162                     OTA_HotelDescriptiveInfoEntity descriptive = null;
163                     string hotelId = string.Empty;
164                     string hotelName = string.Empty;
165                     foreach (OTA_HotelEntity hotelEntity in hotelList.Skip(pageIndex * PageSize).Take(PageSize))
166                     {
167                         descriptive = new OTA_HotelDescriptiveInfoEntity();
168                         descriptive.HotelCode = hotelEntity.HotelCode.ToString();
169                         descriptive.AreaInfoSendAttractions = true;
170                         descriptive.AreaInfoSendRecreations = true;
171                         descriptive.ContactInfoSendData = true;
172                         descriptive.FacilityInfoSendGuestRooms = true;
173                         descriptive.HotelInfoSendData = true;
174                         descriptive.MultimediaObjectsSendData = true;
175                         descriptiveInfoRqEntity.OTA_HotelDescriptiveInfo.Add(descriptive);
176                         hotelId += "," + hotelEntity.HotelCode;
177                         hotelName += "," + hotelEntity.HotelName;
178                         ss += "," + hotelId;
179                     }
180                     if (descriptiveInfoRqEntity == null || descriptiveInfoRqEntity.OTA_HotelDescriptiveInfo.Count == 0)
181                     {
182                         continue;
183                     }
184                     var serviceClient = new CtripHotelClient("CtripHotelService");
185                     string result = serviceClient.OTA_HotelDescriptiveInfoStr(descriptiveInfoRqEntity);
186                     Thread.Sleep(2000);
187                     if (string.IsNullOrEmpty(result))
188                     {
189                         Log.Info("未获取到信息");
190                         return;
191                     }
192                     #region
193                     #region 解析xml
194                    
195                     #endregion
196                     if (entity != null && entity.Head != null)
197                     {
198                         if (entity.Head.ResultCode != null && entity.Head.ResultCode.Equals("Success")
199                             && entity.Head.SubCode != null && entity.Head.SubCode.Equals("Success")
200                             && entity.HotelDescriptiveContent != null && entity.HotelDescriptiveContent.Count > 0)
201                         {
202                             //ThreadPool.QueueUserWorkItem(new WaitCallback(ImportHotelDescriptiveInfoWaitCall), entity);
203                             GetHotelDescriptiveInfo(entity);
204                         }
205                         else
206                         {
207                             //Log.InfoFormat("详细信息出错,ID:{0},Name:{1},详细信息:ResultCode:{2},ResultMsg:{3},SubCode:{4},SubMsg:{5}", hotelEntity.HotelCode, hotelEntity.HotelName,
208                             //    entity.Head.ResultCode, entity.Head.ResultMsg, entity.Head.SubCode, entity.Head.SubMsg);
209                             Log.InfoFormat("返回信息:{0}", result);
210                         }
211                     }
212                     else
213                     {
214                         Log.InfoFormat("未请求到详细信息ID:{0},Name:{1}详细信息", hotelId, hotelName);
215                     }
216                     #endregion
217                 }
218                 Log.InfoFormat("计划循环执行完成:" + ss);
219                 autoEvents[0].Set();
220                 autoEvents[0].Dispose();
221             }
222             catch (Exception ex)
223             {
224                 Log.InfoFormat("详细信息异常:{0}", ex);
225             }
226             Log.Info("请求详细信息完成");
227         }
228 
229         /// <summary>
230         /// 详细信息入库
231         /// </summary>
232         /// <param name="entity"></param>
233         private void GetHotelDescriptiveInfo(OTA_HotelDescriptiveInfoRSEntity entity)
234         {
235             #region
236             CtripHotelDataContext context = new CtripHotelDataContext(Settings.Default.CtripHotelConnectionString);
237             context.Connection.Open();
238             DbTransaction tran = context.Connection.BeginTransaction();
239             context.Transaction = tran;
240             try
241             {
242                 Ctrip_HotelDescriptiveContent descriptiveResult = null;
243                 //Log.InfoFormat("批量存入数据库开始共:{0}条记录--", entity.HotelDescriptiveContent.Count);
244                 foreach (HotelDescriptiveContentEntity contentEntity in entity.HotelDescriptiveContent)
245                 {
246                    
247                 }
248                 context.SubmitChanges();
249                 tran.Commit();
250                 //Log.Info("批量存入数据库结束--");
251             }
252             catch (Exception ex)
253             {
254                 Log.InfoFormat("详细信息入库异常:{0},堆栈:{1}", ex.Message, ex);
255                 Log.InfoFormat("详细信息ID:{0},名称:{1}", entity.HotelDescriptiveContent[0].HotelCode, entity.HotelDescriptiveContent[0].HotelName);
256                 tran.Rollback();
257                 context.Connection.Close();
258                 context.Connection.Dispose();
259             }
260             finally
261             {
262                 context.Connection.Close();
263                 context.Connection.Dispose();
264             }
265             #endregion
266         }
267 
268         public void OTA_HotelRatePlan(object objhotelList)
269         {
270             Log.Info("请求价格计划开始");
271             eventX.WaitOne();
272             string hotelCode = string.Empty;
273             string hotelName = string.Empty;
274             try
275             {
276                 List<OTA_HotelEntity> hotelList = (List<OTA_HotelEntity>)objhotelList;
277                 int pageIndex = 0;
278                 int PageSize = 5;
279                 int pageCount = (int)Math.Ceiling(hotelList.Count / (float)PageSize);
280                 for (pageIndex = 0; pageIndex <= pageCount; pageIndex++)
281                 {
282                     OTA_HotelRatePlanRQEntity rqEntity = new OTA_HotelRatePlanRQEntity();
283                     rqEntity.RatePlan = new List<RatePlanRQEntity>();
284                     RatePlanRQEntity rateEntity = null;
285                     foreach (OTA_HotelEntity hotelEntity in hotelList.Skip(pageIndex * PageSize).Take(PageSize))
286                     {
287                         rateEntity = new RatePlanRQEntity();
288                         rateEntity.AvailRatesOnlyInd = true;
289                         rateEntity.HotelCode = hotelEntity.HotelCode;
290                         rateEntity.Start = DateTime.Now.Date;
291                         rateEntity.End = rateEntity.Start.AddDays(28).Date;
292                         rateEntity.RestrictedDisplayIndicator = "false";
293                         rqEntity.RatePlan.Add(rateEntity);
294                         hotelCode += "," + hotelEntity.HotelCode;
295                         hotelName += "," + hotelEntity.HotelName;
296                     }
297                     if (rqEntity == null || rqEntity.RatePlan.Count == 0)
298                     {
299                         continue;
300                     }
301                     var serviceClient = new CtripHotelClient("CtripHotelService");
302                     string result = serviceClient.OTA_HotelRatePlanStr(rqEntity);
303                     Thread.Sleep(3000);
304                     if (string.IsNullOrEmpty(result))
305                     {
306                         Log.InfoFormat("未获取到ID:{0},名称:{1},价格信息信息", hotelCode, hotelName);
307                         return;
308                     }
309                     OTA_HotelRatePlanRSEntity entity = new OTA_HotelRatePlanRSEntity();
310                     entity.Head = new HeadEntity();
311                     #region 解析xml
312                     
313                     #endregion
314                     if (entity != null && entity.Head != null)
315                     {
316                         if (entity.Head.ResultCode != null && entity.Head.ResultCode.Equals("Success")
317                             && entity.Head.SubCode != null && entity.Head.SubCode.Equals("Success")
318                             && entity.RatePlansList != null && entity.RatePlansList != null && entity.RatePlansList.Count > 0)
319                         {
320                             HotelRatePlanAdd(entity);
321                         }
322                         else
323                         {
324                             Log.InfoFormat("价格计划出错,ID:{0},Name:{1},详细信息:ResultCode:{2},ResultMsg:{3},SubCode:{4},SubMsg:{5}", hotelCode, hotelName,
325                                 entity.Head.ResultCode, entity.Head.ResultMsg, entity.Head.SubCode, entity.Head.SubMsg);
326                         }
327                     }
328                     else
329                     {
330                         Log.InfoFormat("未请求到价格计划ID:{0},Name:{1}详细信息", hotelCode, hotelName);
331                     }
332                 }
333                 autoEvents[1].Set();
334                 autoEvents[1].Dispose();
335             }
336             catch (Exception ex)
337             {
338                 Log.InfoFormat("请求价格计划异常:{0},堆栈:{1}", ex.Message, ex);
339                 Log.InfoFormat("ID:{0},名称:{1},价格信息信息", hotelCode, hotelName);
340             }
341             Log.Info("请求价格计划完成");
342         }
343 
344 
345         /// <summary>
346         /// 初始化价格入库
347         /// </summary>
348         /// <param name="entity"></param>
349         private void HotelRatePlanAdd(OTA_HotelRatePlanRSEntity entity)
350         {
351             CtripHotelDataContext context = new CtripHotelDataContext(Settings.Default.CtripHotelConnectionString);
352             context.Connection.Open();
353             DbTransaction tran = context.Connection.BeginTransaction();
354             context.Transaction = tran;
355             string hotelCode = string.Empty;
356             try
357             {
358                 Ctrip_HotelRatePlan ratePlan = null;
359                 foreach (RatePlanSRSEntity ratePlansEntity in entity.RatePlansList)
360                 {
361                    
362                 }
363                 context.SubmitChanges();
364                 tran.Commit();
365             }
366             catch (Exception ex)
367             {
368                 Log.InfoFormat("名称:{0}价格计划入库异常:{1};", hotelCode, ex);
369                 tran.Rollback();
370                 context.Connection.Close();
371                 context.Connection.Dispose();
372             }
373             finally
374             {
375                 context.Connection.Close();
376                 context.Connection.Dispose();
377             }
378         }
379     }
_劍客的主页 _劍客 | 初学一级 | 园豆:94
提问于:2013-02-01 15:29
< >
分享
最佳答案
0

具体原因是什么我也不清楚,但我用别人封装的方法,不会出现不执行的情况。发给你参考下

View Code
public class OverTimeCntrol
{
        public delegate void Delegate();

        /// <summary>
        /// 执行指定的方法,如果在指定的时间之内没有完成,则中止
        /// </summary>
        /// <param name="func">任务过程</param>
        /// <param name="timeSpan">超时时间</param>
        /// <param name="timeoutCallback">如果超时,则调用该方法</param>
        /// <returns>是否正确执行完毕</returns>
        public static bool CallFuncThread(Delegate func, TimeSpan timeSpan, Delegate timeoutCallback)
        {
            if (func == null)
                throw new ArgumentNullException("func");

            ManualResetEvent resetEvent = new ManualResetEvent(false);
            ManualResetEvent waitThreadEvent = new ManualResetEvent(false);

            Exception error = null;
            Thread thread = null;

            // 将任务加到线程当中
            ThreadPool.QueueUserWorkItem(delegate
            {

                thread = Thread.CurrentThread;
                try { func(); }
                catch (ThreadAbortException) { }
                catch (Exception ex) { error = ex; }

                resetEvent.Set();
                waitThreadEvent.WaitOne();  // 每次线程执行结束都等待后续的处理逻辑
            });

            try
            {
                bool result = resetEvent.WaitOne(timeSpan, false);  // 等待任务的结束

                if (error != null)  // 说明在执行过程中出现异常,直接抛出异常
                    throw error;

                if (!result)
                {
                    if (thread != null)
                    {
                        thread.Abort();  // 此时可以确保该线程没有开始运行新的任务
                        waitThreadEvent.Set();
                    }

                    if (timeoutCallback != null)
                        timeoutCallback();
                }

                return result;
            }
            finally
            {
                waitThreadEvent.Set();  // 最后确保释放线程池线程
            }
        }
}
收获园豆:30
geass.. | 小虾三级 |园豆:1821 | 2013-02-02 18:15

谢谢你帮忙

原因找到了,我写的线程池没有问题,问题是我代码中循环太多,有个地方return掉了,应该break就对了。

_劍客 | 园豆:94 (初学一级) | 2013-02-19 17:01
其他回答(1)
0

在线程窗口里面双击C的线程,看看C线程在什么地方停止运行了,再看看周围是否有可能出现死循环吧

另外可以使用Thread.CurrentThread.ThreadState在watch窗口(ctrl+D+Q)上看看当前线程的状态

滴答的雨 | 园豆:3660 (老鸟四级) | 2013-02-01 15:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册