net异步线程注意事项

  某人(不是我写的)写的异步代码;(还请博友们点评哈~)

              AsyncEventHandler[] asy = new AsyncEventHandler[ResultCount];
                IAsyncResult[] asyncResult = new IAsyncResult[ResultCount];
                for (int j = 0; j < matchedJobs.Length; j++)
                {
                    asy[j] = ThreadJobs;
                    asyncResult[j] = asy[j].BeginInvoke(dataCollection, matchedJobs[j], jobResults, sLotStepSeq, checkReqResultError[j], executedJobList, null, null);
                    ThreadJobs(dataCollection, matchedJobs[j], jobResults, sLotStepSeq, checkReqResultError[j], executedJobList);
                }
                for (int k = 0; k < asy.Length; k++)//必须asy全部处理完成才能往下进行
                {
                    asy[k].EndInvoke(asyncResult[k]);
                }

 

我们看线程池

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ThreadingLearning
{
    class Program
    {static void Main(string[] args)
        {

            //start new .....
            //申明一个Action 的委托list
            List<Action> actions = new List<Action>()
            {
               ()=>{Console.WriteLine("A-1");},
             ()=>{Console.WriteLine("A-2");},
             ()=>{Console.WriteLine("A-3");},
             ()=>{Console.WriteLine("A-4");}

            };

            //遍历输出结果;
            foreach (var action in actions)
            {
    
                ThreadPool.QueueUserWorkItem(p => action(), null);
            }
         
            Console.ReadLine();

        }
    }
}

 结果:

A-1 过了就是A-4 则说明主线程(for循环)的执行速度,比子线程执行的速度快,或者说优先级高。(不一定,总体是这样的)

网上还看到了这样的结果:

  解释出现这样现象的原因:

  醒悟过来:由于被置于ThreadPool中的操作时异步的,还没有来的执行的时候,ation已经被for循环改变,永远是同一个ation对象!

  出现的情况,那要根据个人的cpu情况了,

 

解决方法一:Thread.Sleep(N)

  //遍历输出结果;
            foreach (var action in actions)
            {
                Thread.Sleep(10);
                //Thread.Sleep(N)是对当前线程阻塞一定时间,
                //那这个处理不论是主线程还是线程池中的线程都是有效果的,
                //至少为线程池中的线程的请求与启动赢得了时间
                ThreadPool.QueueUserWorkItem(p => action(), null);
            }

解决方法二:使用中间变量;

           foreach (var action in actions)
            {
                var temp = action;
                ThreadPool.QueueUserWorkItem(p => temp(), null);
            }

下面这种情况会出现bug;会出现如图二的bug,

 //遍历输出结果;
            var action=actions[0];  //先随便赋一个值,
            foreach ( var v in actions)
            {
                action = v;  
                ThreadPool.QueueUserWorkItem(state => action(), null);
            }
         

结果:bug

 

posted @ 2016-07-06 12:27  咕-咚  阅读(212)  评论(0编辑  收藏  举报