public void Run()
        {
            System.Diagnostics.Trace.WriteLine(string.Format("[PID:{2}] {0}.{1}() begin", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId));

            CurrentIdx = 0;
            GiftBase gift     = null;
            Reletive fromWhom = null;

            BuyGift(out gift, out fromWhom);
            //System.Diagnostics.Trace.WriteLine(string.Format("[PID:{0}] A gift has been bought.", Thread.CurrentThread.ManagedThreadId));

            if (null != _ares)
            {
                Array.Clear(_ares, 0, _ares.Length);
            }
            _ares = _boxes.Select(x => new AutoResetEvent(false)).ToArray();

            var _dlgtWhatsInBox = new DefDlgt_WhatsInBox <GiftBase, Reletive>(DlgtFunc_WhatsInBox);

            _dlgtWhatsInBox.BeginInvoke(gift, _boxes[CurrentIdx], fromWhom, baby, Acb_WhatsInBox, _dlgtWhatsInBox);

            System.Diagnostics.Trace.WriteLine(string.Format("[PID:{2}] {0}.{1}() See what's in box...", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId));
            WaitHandle.WaitAll(_ares);

            System.Diagnostics.Trace.WriteLine(string.Format("[PID:{2}] {0}.{1}() end", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId));
        }
        public string GiftIntoBox(GiftBase gift, Reletive fromWhom)
        {
            string rslt = string.Format("A/An {0} from {1} has been put in the {2}.", gift, fromWhom, ToString());

            System.Diagnostics.Trace.WriteLine(string.Format("[PID:{3}] {0}.{1}(), {2}", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, rslt, Thread.CurrentThread.ManagedThreadId));
            return(rslt);
        }
        void BuyGift(out GiftBase gift, out Reletive fromWhom)
        {
            switch (_seed = _random.Next(5))
            {
            case 0: { fromWhom = new Father("Baby's Dad"); break; }

            case 1: { fromWhom = new Grandpa("Baby's grandpa"); break; }

            case 2: { fromWhom = new Grandma("Baby's grandma"); break; }

            case 5: { fromWhom = new Baby("Baby"); break; }

            case 4:
            default: { fromWhom = new Mother("Baby's Mom"); break; }
            }
            switch (_seed = _random.Next(3))
            {
            case 0: { gift = new Gift_Bike("300", fromWhom.ToString()); break; }

            case 1: { gift = new Gift_Toy("15", fromWhom.ToString()); break; }

            case 2:
            default: { gift = new Gift_Book("75", fromWhom.ToString()); break; }
            }
        }
        void DlgtFunc_WhatsInBox <TGift, TReletive>(TGift gift, TBox box, TReletive fromWhom, Baby baby)
        {
            System.Diagnostics.Trace.WriteLine(string.Format("[PID:{2}] {0}.{1}() begin", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId));
            GiftBase g = gift as GiftBase;
            Reletive r = fromWhom as Reletive;

            box.GiftIntoBox(g, r);
            //System.Diagnostics.Trace.WriteLine(string.Format("[PID:{2}] {0}.{1}() gift has been packaged in box", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId));
            r.GiveToBady(box, baby);
            //System.Diagnostics.Trace.WriteLine(string.Format("[PID:{2}] {0}.{1}() box has been given to baby", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId));
            baby.OpenBox(box);
            //System.Diagnostics.Trace.WriteLine(string.Format("[PID:{2}] {0}.{1}() box has been openned.", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId));
            baby.BabyResponse();
            //System.Diagnostics.Trace.WriteLine(string.Format("[PID:{2}] {0}.{1}() baby responsed.", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId));
            System.Diagnostics.Trace.WriteLine(string.Format("[PID:{2}] {0}.{1}() end", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId));
        }
 void Acb_WhatsInBox(IAsyncResult iar)
 {
     System.Diagnostics.Trace.WriteLine(string.Format("[PID:{2}] {0}.{1}() begin", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId));
     if (_boxes.Count > CurrentIdx)
     {
         _ares[CurrentIdx].Set();
         CurrentIdx++;
         if (_boxes.Count > CurrentIdx)
         {
             GiftBase gift     = null;
             Reletive fromWhom = null;
             BuyGift(out gift, out fromWhom);
             var _dlgtWhatsInBox = new DefDlgt_WhatsInBox <GiftBase, Reletive>(DlgtFunc_WhatsInBox);
             //System.Diagnostics.Trace.WriteLine(string.Format("[PID:{2}] {0}.{1}() gift has been bought", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId));
             _dlgtWhatsInBox.BeginInvoke(gift, _boxes[CurrentIdx], fromWhom, baby, Acb_WhatsInBox, _dlgtWhatsInBox);
             //System.Diagnostics.Trace.WriteLine(string.Format("[PID:{2}] {0}.{1}() see what's in box...", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId));
         }
     }
     (iar.AsyncState as DefDlgt_WhatsInBox <GiftBase, Reletive>).EndInvoke(iar);
     System.Diagnostics.Trace.WriteLine(string.Format("[PID:{2}] {0}.{1}() end", MethodBase.GetCurrentMethod().DeclaringType.Name, MethodBase.GetCurrentMethod().Name, Thread.CurrentThread.ManagedThreadId));
 }