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 }
//模拟源数据 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; }
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(); }