多线程与异步编程知识简单总结

mac2022-06-30  78

一些基本概念:

运行一个程序所需要的所有资源就是一个进程。

一个进程可以有多个线程,且最少有一个线程。

线程是cpu调度的最小单位。

可以把进程理解为一个公司,一个线程理解为公司里的一个员工。

应用程序域:可以在一个进程中启动多个应用程序(在一个exe程序中再启动另一个exe程序,在任务管理器中只启动了一个进程~)。

 

什么时候用多线程呢?

  1、一个任务需要较长的耗时,但是我们不想等,想要在这个任务执行的时候,同时干点别的事

  2、cpu比较闲,其他的操作却比较忙的时候可以使用多线程。

  3、为了防止界面卡死,可以使用多线程。

 下面上代码:

1、启动一个线程 ,执行一个无参数的方法

// 1.创建一个线程对象,把DoWhile方法传递进去,表示该线程启动后会执行这个方法 t1 = new Thread(new ThreadStart(DoWhile)); t1.IsBackground = true;// 把当前线程设置为后台线程,后台线程在所有前台线程执行完毕后自动退出。默认创建的进程都是“前台线程” // 2.启动这个线程 t1.Start(); // 向操作系统请求启动线程。 private void DoWhile() {      while (true)      {          Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));          Thread.Sleep(500);      } }

  

2、启动一个线程,执行一个需要一个参数的方法

Thread t1 = new Thread(new ParameterizedThreadStart(M2)); t1.Start(100); static void M2(object n) { int max = (int)n; int sum = 0; for (int i = 1; i < max; i++) { sum += i; } Console.WriteLine(sum); }

3、启动一个线程,执行带参数的方法,几个参数都行!

//把要执行的方法封装到一个类中 //将执行方法所需要的参数封装为类的属性 //将该方法改为一个无参的方法,原本方法中的参数用类的属性代替。 //为这个类的属性赋值,就相当于为方法传参 MyClass mc = new MyClass(); mc.Number = 101; Thread t1 = new Thread(new ThreadStart(mc.M3)); t1.Start(); public class MyClass { public int Number { get; set; } public void M3() { int sum = 0; for (int i = 1; i < this.Number; i++) { sum += i; } Console.WriteLine(sum); } }

4、启动一个线程,执行带返回值的方法

// 创建一个后台执行者对象 BackgroundWorker backWorker = new BackgroundWorker(); // 设置该对象在后台执行的方法 backWorker.DoWork += new DoWorkEventHandler(backWorker_DoWork); // 设置后台方法执行完毕后触发的事件 backWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backWorker_RunWorkerCompleted); // 开始执行 backWorker.RunWorkerAsync(new int[] { 1, 100 }); // 后台执行的方法 static void backWorker_DoWork(object sender, DoWorkEventArgs e) { if (e.Argument != null) { int[] arr = e.Argument as int[]; //将返回值赋给e.Result e.Result = Sum(arr[0], arr[1]); } } // 后台方法执行完毕后触发的事件 static void backWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Console.WriteLine("最后输出结果是:{0}", e.Result); }

5、后台线程改变界面

public delegate void ShowMsgDelegate(string msg); private void ShowMsg(string msg) {   label1.Text = msg; } ShowMsgDelegate showMsgDelegate= new ShowMsgDelegate(ShowMsg); string msg="hello"; Invoke(showMsgDelegate,msg);

 6.异步编程

    public delegate int HaoShiDelegate(int startValue); public HaoShiDelegate HaoShi = HaoShiMethod; private void button1_Click(object sender, EventArgs e) { // 第一个参数为执行异步方法需要的参数 // 第二个参数为回调方法 // 第三个参数为传递给回调方法的一些信息,参数类型为object,如果需要传递多个信息,则可以将这些信息封装到一个类中。 HaoShi.BeginInvoke(1000, CallBackMethod, "啦啦啦啦啦啦"); } private static int HaoShiMethod(int startValue) { int sum = startValue; for (int i = 0; i < 100; i++) { sum += i; } Thread.Sleep(5000); return sum; } // 回调函数只能有一个参数,并且参数的类型只能是IAsyncResult private void CallBackMethod(IAsyncResult r) { // 获取原始的委托变量 AsyncResult result = (AsyncResult)r; HaoShiDelegate d = (HaoShiDelegate)result.AsyncDelegate; // 获取BeginInvoke中传递的最后一个object参数 string lastParam = (String)result.AsyncState;        // 通过调用原始委托变量的EndInvoke方法获得异步方法的返回值。 int num = d.EndInvoke(r); MessageBox.Show("耗时方法的返回值是:" + num + " 最后一个参数是 " + lastParam); }

 

  

摇奖机小练习:http://files.cnblogs.com/files/FangZhaohu/摇奖机小练习.zip

 异步编程小demo:http://files.cnblogs.com/files/FangZhaohu/异步编程小demo.zip

  

转载于:https://www.cnblogs.com/FangZhaohu/p/4594235.html

最新回复(0)