C#多线程(二)

二,线程的同步和异步
如果看到我关于委托应用(二)的朋友应该发现了this.Invoke(delegate) 的用法,这是实际是线程的调用,跨线程调用的使用 ,和new delegate().Invoke() 是不一样的,但是都可去调用委托的同步异步!
概念
同步:发起调用,必须等着完成后,才能进入下一行。
异步:发起调用,不用等着完成,直接进入下一行,原来的操作也会有新的执行流来完成。

一,线程同步
1,同步方法卡界面,UI线程(主线程)忙于计算,无法响应别的操作
2, 同步方法慢,只有一个线程参与计算
3,但是在实际开发中反而是单进程单线程的应有比价多,像node,redis就是典型的单进程单线程!
在这里插入图片描述
这里,我开始控制台,同时开启了一个窗体,窗体页面执行了一个很耗时间的计算,那么在执行的过程中,由于是同步方法,所以form1则假死了,无法进行其他操作!这就是同步 !
代码如下

  class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }

    }
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Console.WriteLine("开启线程之旅!,打开窗体");
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Console.WriteLine();
            Console.WriteLine(" 同步方法开始,线程ID为 {0}", Thread.CurrentThread.ManagedThreadId);                 
            for (int i = 1; i <= 6; i++)   //特意执行了6次
            { 
                string name = string.Format("[第{0}_{1}", "button1_Click]",  i);
                this.DoSomethingLong(name);
            }
            Console.WriteLine(" button1_Click 同步方法结束,线程ID为 {0} ", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine();
        }


        #region PrivateMethod
        /// <summary>
        /// 一个耗时耗资源的测试方法
        /// </summary>
        /// <param name="name"></param>
        private void DoSomethingLong(string name)
        {
            Console.WriteLine("--start,线程发起者:{0},ID:{1},time:{2} --",
                name, Thread.CurrentThread.ManagedThreadId.ToString("00"), DateTime.Now.ToString("HHmmss:fff"));

            long lResult = 0;
            for (int i = 0; i < 1_000_000_000; i++)
            {
                lResult += i;
            }
            Console.WriteLine("**end,线程发起者:{0},ID: {1} ,time:{2},sum: {3} **",
                name, Thread.CurrentThread.ManagedThreadId.ToString("00"), DateTime.Now.ToString("HHmmss:fff"), lResult);
        }
        #endregion
    }

2多线程异步
特点
1,异步多线程不卡界面,计算交给子线程,UI线程闲置,可以响应别的操作,这些场景可以使用
Winform–文件上传/订单提交—异步多线程
Winform–网络检测, 数据发包–异步多线程
MVC—用户注册发邮件/发短信—异步多线程发邮件

2,异步多线程方法快
但并不是越多越好, 因为:
1资源有限
2线程调度损耗
线程并不是越多越好,除非真的需要用资源换性能

3,异步多线程的无序性:
启动无序:非阻塞,同一时间申请线程,但是操作系统无法掌控
执行时间不确定:因为CPU的调度是OS完成的(线程优先级也只是影响分配策略)
结束无序:以上叠加就是的
多线程是很难掌控,但是也有办法(顺序控制,回调/等待/信号量)
多线程开发时,一定不要通过延迟一下这种方式来控制顺序(非常不安全的做法)

接下来感受异步执行

在这里插入图片描述
无序体现出来了,同时这个这个form1是可以控制的,是可移动的说明线程没有阻塞
代码如下:

 private void button2_Click(object sender, EventArgs e)
        {
            Console.WriteLine();
            Console.WriteLine("异步方法开始,线程ID为 {0}", Thread.CurrentThread.ManagedThreadId);

            // Action<string> action = new Action<string>(DoSomethingLong);  

            Action<string> action = DoSomethingLong;

            for (int i = 1; i <= 5; i++)
            {
                string name = string.Format("[{0}_第{1}次", "button2_Click]", i);

                AsyncCallback callback = new AsyncCallback(Call);
                IAsyncResult Result = action.BeginInvoke(name, callback, "aaa");   //这个aaa就是回调中的 AsyncState 的值,很多时候就是用这个参传值给回调使用的
			 //   action.EndInvoke(Result);  //调用完成之后接收回调
               // action.Invoke(name);//  同步方法
            }

            Console.WriteLine(" button2_Click 异步方法结束,线程ID为 {0} ", Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine();
        }

        void Call(IAsyncResult async)
        {
            if (async.IsCompleted)
            {
					Console.WriteLine("回调显示状态" + async.AsyncState);  //调用成功之后执行回调
            }    
        }

暂时写到这里!欢迎指点!

猜你喜欢

转载自blog.csdn.net/weixin_42780928/article/details/92796094