美文网首页
C#同步调用、异步调用、异步回调、Task类、async/wai

C#同步调用、异步调用、异步回调、Task类、async/wai

作者: 易点梅 | 来源:发表于2021-07-29 09:44 被阅读0次
      class AsyncClass
        {
            //声明委托
            private delegate int AddHandler(int a, int b);
    
            //代理方法
            public int Add(int a, int b)
            {
                Thread.Sleep(1000 * 3);
                Console.WriteLine("ThreadID--" + Thread.CurrentThread.ManagedThreadId);
                return a + b;
            }
    
            //同步调用,阻塞当前线程,顺序执行
            public void Tongbu()
            {
                AddHandler handler = new AddHandler(Add);
                int result = handler.Invoke(8, 5);
    
                Console.WriteLine(result);
    
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffffff"));
    
                Console.WriteLine(handler(4, 5));
    
                Console.WriteLine("Tongbu Done!");
            }
    
            //异步调用
            public void Yibu()
            {
                AddHandler handler = new AddHandler(Add);
    
                for (int i = 1; i <= 5; i++)
                {
                    //相当于另开了5个线程去执行Add方法
                    IAsyncResult result = handler.BeginInvoke(i, i, new AsyncCallback(CallBack), "AsycState:OKaaa");
                }
    
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff"));
    
                //没有回调时也必须使用EndInvoke方法。BeginInvoke和EndInvoke必须同时出现,否则可能发生内存泄漏
                //Console.WriteLine(handler.EndInvoke(result));
    
                Console.WriteLine("Yibu Done!");
    
                Console.ReadKey();
            }
    
            //异步回调方法
            public void CallBack(IAsyncResult result)
            {
                //AsyncResult 是IAsyncResult接口的一个实现类,空间:System.Runtime.Remoting.Messaging
                //AsyncDelegate 属性可以强制转换为用户定义的委托的实际类。
                AddHandler handler = (AddHandler)((AsyncResult)result).AsyncDelegate;
    
                Console.WriteLine(handler.EndInvoke(result));
                Console.WriteLine(result.AsyncState);
                Console.WriteLine("CallBack Done!");
            }
    
    
            //线程池
            AutoResetEvent are = new AutoResetEvent(false); //信号灯
            int num = 10;
            public void ThreadPoolTest()
            {
                ThreadPool.SetMinThreads(1, 1);
                ThreadPool.SetMaxThreads(5, 5);
    
                for (int i = num; i >= 0; i--)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(CallBack2),i.ToString());
                }
    
                Console.WriteLine("主线程执行!");
    
                are.WaitOne();//阻塞当前线程,直到are执行了Set方法
                Console.WriteLine("主线程结束!");
                Console.ReadKey();
            }
    
            //线程池回调方法
            public void CallBack2(object obj)
            {
                num--;
                Console.WriteLine(string.Format("{0}:第{1}个线程", DateTime.Now.ToString(), obj.ToString()));
                Thread.Sleep(1000);
                if (num == -1)
                    are.Set();
            }
    
    
            //Task创建和运行  无返回值
            public void TaskTest()
            {
                //方式一
                Task task1 = new Task(() =>
                {
                    Thread.Sleep(200);
                    Console.WriteLine("void当前线程ID = {0}", Thread.CurrentThread.ManagedThreadId);
                });
                task1.Start();
    
                //方式二
                Task task2 = Task.Factory.StartNew(() =>
                {
                    Thread.Sleep(200);
                    Console.WriteLine("void当前线程ID = {0}", Thread.CurrentThread.ManagedThreadId);
                });
    
                //方式三
                Task task3 = Task.Run(() =>
                {
                    Thread.Sleep(200);
                    Console.WriteLine("void当前线程ID = {0}", Thread.CurrentThread.ManagedThreadId);
                });
    
                Console.WriteLine("主线程 void");
                Console.WriteLine("主线程 void Done!");
            }
    
            //Task创建和运行  有返回值
            public void TaskReturnTest()
            {
                //方式一
                Task<string> task1 = new Task<string>(() =>
                {
                    Thread.Sleep(200);
                    return string.Format("当前线程ID = {0}", Thread.CurrentThread.ManagedThreadId);
                });
                //task1.Start();
    
                //方式二
                Task<string> task2 = Task.Factory.StartNew<string>(() =>
                {
                    Thread.Sleep(200);
                    return string.Format("当前线程ID = {0}", Thread.CurrentThread.ManagedThreadId);
                });
    
                //方式三
                Task<string> task3 = Task.Run<string>(() =>
                {
                    Thread.Sleep(200);
                    return string.Format("当前线程ID = {0}", Thread.CurrentThread.ManagedThreadId);
                });
    
                task1.RunSynchronously(); //阻塞主线程,直到task1线程执行完
    
                task2.Wait(); //等待task2执行完
    
                Task.WaitAll(new Task[] { task1, task2, task3 }); //等待所有task执行完
    
                Task.WaitAny(new Task[] { task1, task2, task3 }); //等待任何一个task执行完
    
                Console.WriteLine("主线程 Return");
                Console.WriteLine(task1.Result);
                Console.WriteLine(task2.Result);
                Console.WriteLine(task3.Result);
    
                //至少一个task执行完,去执行后续操作
                Task.WhenAny(new Task[] { task1, task2, task3 }).ContinueWith((t) =>
                {
                    Console.WriteLine("至少有一个task执行完了。。。。。" );
                });
    
                //所有的task执行完,去执行后续操作
                Task.WhenAll(new Task[] { task1, task2, task3 }).ContinueWith((t) =>
                {
                    Console.WriteLine("所有的task都执行完了。。。。。");
                });
    
                //等同于Task.WhenAny
                Task.Factory.ContinueWhenAny(new Task[] { task1, task2, task3 }, (t) =>
                {
                    Console.WriteLine("至少有一个task执行完了。。。。。");
                });
    
                //等同于Task.WhenAll
                Task.Factory.ContinueWhenAll(new Task[] { task1, task2, task3 }, (t) =>
                {
                    Console.WriteLine("所有的task都执行完了。。。。。");
                });
    
                Console.WriteLine("主线程 Return Done!");
    
                Console.ReadKey();
            }
    
            //Task取消任务,并设置取消任务后触发的事件
            public void TaskCancelTest()
            {
                CancellationTokenSource source = new CancellationTokenSource();
    
                //注册任务取消触发的事件
                source.Token.Register(() =>
                {
                    Console.WriteLine("任务已取消");
                });
                int index = 0;
                Task task = new Task(() =>
                {
                    while(!source.IsCancellationRequested)
                    {
                        Thread.Sleep(500);
                        Console.WriteLine(++index);
                    }
                });
                task.Start();
    
                //10000毫秒后停止运行task
                source.CancelAfter(10000);
    
                Console.ReadKey();
            }
    
    
            //异步方法 Async、await
            public static async Task<string> GetFileContentAsync(string fileName)
            {
                FileStream fs = new FileStream(fileName, FileMode.Open);
                var bytes = new byte[fs.Length];
                Console.WriteLine("开始读取文件");
                int len = await fs.ReadAsync(bytes, 0, bytes.Length);
                string result = Encoding.Default.GetString(bytes);
                return result;
            }
    
            public static async Task GetFileContentAsync2(string fileName)
            {
                FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                var bytes = new byte[fs.Length];
                Console.WriteLine("开始读取文件");
                int len = await fs.ReadAsync(bytes, 0, bytes.Length);
                string result = Encoding.UTF8.GetString(bytes);
                return;
            }
    
            public static async void GetFileContentAsync3(string fileName)
            {
                FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                var bytes = new byte[fs.Length];
                Console.WriteLine("开始读取文件");
                int len = await fs.ReadAsync(bytes, 0, bytes.Length);
                string result = Encoding.UTF8.GetString(bytes);
            }
        }
    

    一次运行结果:

    image.png

    相关文章

      网友评论

          本文标题:C#同步调用、异步调用、异步回调、Task类、async/wai

          本文链接:https://www.haomeiwen.com/subject/ldsxvltx.html