异步编程,任务与并行编程,任务同步

异步编程:

同步:按照顺序,一件事情做完了才能接着做一件事情,比如主函数中执行多个顺序方法和语句,只有上一条语句或者方法执行完毕才能执行下一个方法或者语句。
异步:开始一个任务(比如一个方法)后,让任务在另一个线程中执行,本线程可以继续执行别的事情,然后等待那个任务执行完毕

比如一个UI按钮,UI就相当于一个主函数,而按钮事件就是调用的方法,如果使用同步,那么在方法执行期间,整个ui界面就会发生阻塞,从而导致无法做任何操作

多线程和异步不是同一个概念,多线程是用于实现异步的一种方式。
异步可以用线程来实现也可以不用线程实现,C#使用线程来实现

传统方法一,异步模式,使用委托的BeginInvoke及EndInvoke

class Program
    {
        public delegate int FooDelegate(string s);

        static void Main(string[] args)
        {
            Console.WriteLine("主线程" + Thread.CurrentThread.ManagedThreadId);

            FooDelegate fooDelegate = Foo;
            IAsyncResult result = fooDelegate.BeginInvoke("Hello World", null, null);

            Console.WriteLine("主线程继续执行做其他事...");

            int n = fooDelegate.EndInvoke(result);
            Console.WriteLine("回到主线程" + Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("结果是" + n);
            Console.ReadKey(true);

        }

        public static int Foo(string s)
        {
            Console.WriteLine("函数所在线程" + Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("异步线程开始执行:" + s);
            Thread.Sleep(1000);
            return s.Length;
        }
    }

传统方法二,基于事件,对于完成后打印结果等后续语句,使用委托回调

class Program_Callback
    {
        public delegate int FooDelegate(string s);

        static void Main(string[] args)
        {
            Console.WriteLine("主线程" + Thread.CurrentThread.ManagedThreadId);

            FooDelegate fooDelegate = Print;
            IAsyncResult result = fooDelegate.BeginInvoke("Hello World", PrintComplete, fooDelegate);//这里回调PrintComplete方法
            Console.WriteLine("主线程继续执行做其他事...");
            Console.ReadKey(true);

        }

        public static int Print(string s)
        {
            Console.WriteLine("函数所在线程" + Thread.CurrentThread.ManagedThreadId);
            Console.WriteLine("异步线程开始执行:" + s);
            Thread.Sleep(1000);
            return s.Length;
        }

        public static void PrintComplete(IAsyncResult result)
        {
            (result.AsyncState as FooDelegate).EndInvoke(result);
            Console.WriteLine("当前线程结束" + result.AsyncState.ToString());
        }
    }

最新方式,基于任务,使用await和async关键字和Task类型

await 表示等待任务执行,用来调用返回任务的方法,或者阻塞等待一个任务执行完毕
async修饰一个方法,表示其中有await语句

await task相当于EndInvoke()用于阻塞等待任务线程执行完毕

    class Program_awaitAndAsync
    {
        static async Task Main(string[] args)
        {
            Task<double> task = FacAsync(10);

            Console.WriteLine("主函数继续执行。。。");
            for (int i = 0; i < 10; i++) Console.WriteLine("main");

            double result = await task;//此处await对程序进行阻塞,直到task执行完毕 才会执行接下来的语句

            Console.WriteLine("结果为"+result);
            Console.ReadKey(true);
        }

        public static Task<double> FacAsync(int n)
        {
            //Run会开启一个新的线程来执行委托的程序
            return Task<double>.Run(() => {
                double s = 1; for (int i = 1; i < n; i++) {
                    s = s + i;
                    Console.WriteLine("task");
                }
                return s;
            });
        }

        async void Test()
        {
            double result = await FacAsync(10);
            Console.WriteLine(result);
        }
    }

猜你喜欢

转载自www.cnblogs.com/xiaoahui/p/12821436.html