public override void ShowUsage()
        {
            #region ThreadStart和ParameterizedThreadStart创建非常简单,但难于管理

            Console.WriteLine("Main Thread Id is:" +
                  Thread.CurrentThread.ManagedThreadId);

            //Message message = new Message();
            //Thread thread = new Thread(new ThreadStart(message.ShowMessage));
            //thread.Start();

            Message message = new Message();
            Thread thread = new Thread(new ParameterizedThreadStart(message.ShowMessage));

            //ThreadStart启动的线程默认为前台线程,而系统必须等待所有前台线程运行结束后,应用程序域才会自动卸载。
            //通过设置线程的IsBackground为true显示指定线程是否为后台线程,若为后台线程,应用程序域将在主线程完成时就被卸载,而不会等待异步线程的运行。

            thread.IsBackground = true;                                         //设置线程为后台线程
            Person p = new Person();
            p.Name = "Jack";
            p.Age = 21;
            thread.Start(p);                                                    //调用方法时传入参数值

            Console.WriteLine("Do something ..........!");
            Console.WriteLine("Main thread working is complete!");
            Console.WriteLine("Main thread sleep!");
            //Thread.Sleep(5000);//无法预知子线程的运行时间,所以用主线程等待自定义时间来结束运行是不明智的
            //于是有了以下方法
            thread.Join();//以子线程的Join方法来通知主线程等待其执行完毕之后再结束

            #endregion
        }
Example #2
0
        //模拟源数据
        private IList<Person> GetPersonList()
        {
            var personList = new List<Person>();

            var person1 = new Person();
            person1.ID = 1;
            person1.Name = "Leslie";
            person1.Age = 30;
            personList.Add(person1);
            return personList;
        }
Example #3
0
        static void Main(string[] args)
        {
            Person p = new Person();
            p.Name = "何佳迅";
            p.Age = 24;
            p.ID = 1;

            XMLSerializer.Serialize<Person>(p, AppDomain.CurrentDomain.BaseDirectory + "1.xml");

            Console.ReadKey();
        }
        public override void ShowUsage()
        {
            ThreadMessage("Main Thread");
            //创建委托
            MyDelegate myDelegate = new MyDelegate(Hello);
            //如果在使用myDelegate.BeginInvoke后立即调用myDelegate.EndInvoke,在异步线程未完成工作以前主线程将处于阻塞状态,等到异步线程结束获取计算结果后,主线程才能继续工作,这明显无法展示出多线程的优势。此时可以好好利用IAsyncResult 提高主线程的工作性能
            Console.WriteLine("请选择使用何种方式发起异步线程未完成状态的判断?");
            Console.WriteLine("1):轮询IsCompleted  2):WaitOne  3)WaiAll  4)回调函数");
            //在异步线程未完成前执行其他工作
            ConsoleKeyInfo key = Console.ReadKey(true);
            //记录开始任务时的时间
            DateTime startWorkTime = DateTime.Now;

            if (key.Key == ConsoleKey.D1 || key.Key == ConsoleKey.D2 || key.Key == ConsoleKey.D3)
            {
                //异步调用委托,获取计算结果
                IAsyncResult result = myDelegate.BeginInvoke("Frost", null, null);
                switch (key.Key)
                {
                    #region 1、轮询result.IsCompleted属性
                    case ConsoleKey.D1:
                        while (!result.IsCompleted)
                        {
                            Thread.Sleep(200);                      //虚拟操作
                            TimeSpan timeSpan = DateTime.Now - startWorkTime;
                            Console.WriteLine("This is reported by main thread, async thread has done work for {0} ms.", timeSpan.TotalMilliseconds);
                        }
                        break;
                    #endregion
                    #region 2、WaitOne属性判断
                    //除此以外,也可以使用WailHandle完成同样的工作,WaitHandle里面包含有一个方法WaitOne(int timeout),它可以判断委托是否完成工作,在工作未完成前主线程可以继续其他工作。运行下面代码可得到与使用 IAsyncResult.IsCompleted 同样的结果,而且更简单方便 。
                    case ConsoleKey.D2:
                        while (!result.AsyncWaitHandle.WaitOne(200))
                        {
                            TimeSpan timeSpan = DateTime.Now - startWorkTime;
                            Console.WriteLine("This is reported by main thread, async thread has done work for {0} ms.", timeSpan.TotalMilliseconds);
                        }
                        break;
                    #endregion
                    #region 3、WaitAll属性判断
                    //当要监视多个运行对象的时候,使用IAsyncResult.WaitHandle.WaitOne可就派不上用场了。
                    //幸好.NET为WaitHandle准备了另外两个静态方法:WaitAny(waitHandle[], int)与WaitAll (waitHandle[] , int)。
                    //其中WaitAll在等待所有waitHandle完成后再返回一个bool值。
                    //而WaitAny是等待其中一个waitHandle完成后就返回一个int,这个int是代表已完成waitHandle在waitHandle[]中的数组索引。
                    //下面就是使用WaitAll的例子,运行结果与使用 IAsyncResult.IsCompleted 相同。
                    //等待异步方法完成,调用EndInvoke获取运行结果
                    case ConsoleKey.D3:
                        //加入所有检测对象
                        WaitHandle[] waitList = new WaitHandle[] { result.AsyncWaitHandle };
                        while (!WaitHandle.WaitAll(waitList, 200))
                        {
                            TimeSpan timeSpan = DateTime.Now - startWorkTime;
                            Console.WriteLine("Work has being doing for {0} ms.", timeSpan.TotalMilliseconds);
                        }
                        break;
                    #endregion
                }
                string data = myDelegate.EndInvoke(result);
                Console.WriteLine(data);
            }
            else if (key.Key == ConsoleKey.D4)
            {
                #region 4、回调函数
                //使用轮询方式来检测异步方法的状态非常麻烦,而且效率不高,有见及此,.NET为 IAsyncResult BeginInvoke(AsyncCallback , object)准备了一个回调函数。使用 AsyncCallback 就可以绑定一个方法作为回调函数,回调函数必须是带参数 IAsyncResult 且无返回值的方法: void AsycnCallbackMethod(IAsyncResult result) 。在BeginInvoke方法完成后,系统就会调用AsyncCallback所绑定的回调函数,最后回调函数中调用 XXX EndInvoke(IAsyncResult result) 就可以结束异步方法,它的返回值类型与委托的返回值一致。
                //建立Person对象,用作参数
                Person person = new Person();
                person.Name = "Elva";
                person.Age = 27;
                //第一个参数为委托方法对应的参数,第二个为回调函数,第三个为传入的参数
                IAsyncResult result = myDelegate.BeginInvoke("Frost", new AsyncCallback(Completed), person);
                while (!result.IsCompleted)
                {
                    Thread.Sleep(200);                      //虚拟操作
                    TimeSpan timeSpan = DateTime.Now - startWorkTime;
                    Console.WriteLine("This is reported by main thread, async thread has done work for {0} ms.", timeSpan.TotalMilliseconds);
                }
                //可以看到,主线在调用BeginInvoke方法可以继续执行其他命令,而无需再等待了,这无疑比使用轮询方式判断异步方法是否完成更有优势。
                //在异步方法执行完成后将会调用AsyncCallback所绑定的回调函数,注意一点,回调函数依然是在异步线程中执行,这样就不会影响主线程的运行,这也使用回调函数最值得青昧的地方。
                //在回调函数中有一个既定的参数IAsyncResult,把IAsyncResult强制转换为AsyncResult后,就可以通过 AsyncResult.AsyncDelegate 获取原委托,再使用EndInvoke方法获取计算结果。
                #endregion
            }
            Console.ReadKey();
        }