C# 同步异步的区别

程序是为完成特定任务,用户某种语言编写的一组指令的集合,它是一段静态的代码,而进程是程序的一次执行的过程,是系统进行调度和资源分配的一个独立的单元。

 

先弄清楚进程和线程的区别:

【进程的本质】程序的一次执行的过程,是系统进行调度和资源分配的一个独立的单元。

【线程的本质】
  线程不是一个计算机硬件的功能,而是操作系统提供的一种逻辑功能,线程本质上是进程中一段并发运行的代码,所以线程需要操作系统投入CPU资源来运行和调度,是比进程更小的执行单位,一个进程在执行的过程中,可以产生多个线程,形成多条执行线索。

c#中同步操作和异步操作的区别:

百度资料:找到了这样一句话:

同步方法调用在程序继续执行之前需要等待同步方法执行完毕返回结果
异步方法则在被调用之后立即返回以便程序在被调用方法完成其任务的同时执行其它操作。

同步:比如有三个程序要执行,必须第一个程序被触发,执行结束了吗,才轮到其他程序执行。

异步:所有程序的执行不需要同步,可以多个触发,互相独立的执行相应的指令。

很绕口,认真读几遍,便会发现,其实概念很清楚:自己简单的理解是多个程序同步执行和不同步执行的区别,

在C#中,.NET框架基类库中有好几种类都可以提供同步和异步的方法调用。
因为同步方法调用会导致程序流程中途等待,所以采用同步方法的情况下往往会导致程序执行的延迟
相比来说,在某些条件下选择异步方法调用就可能更好一些
例如,有的时候程序需要给多个Web服务发出请求,还有远程处理信道(HTTP、TCP)和代理,这时就最好采用异步方法。

还是看代码:

以下转载》》click here

通过代码定义一个委托和下面三个示例将要调用的方法:


    public delegate int AddHandler(int a,int b);
    public class 加法类
    {
        public static int Add(int a, int b)
        {
            Console.WriteLine("开始计算:" + a + "+" + b);
            Thread.Sleep(3000); //模拟该方法运行三秒
            Console.WriteLine("计算完成!");
            return a + b;
        }
    }
同步调用

委托的Invoke方法用来进行同步调用。同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行。

public class 同步调用
{
        static void Main()
        {
            Console.WriteLine("===== 同步调用 SyncInvokeTest =====");
            AddHandler handler = new AddHandler(加法类.Add);
            int result = handler.Invoke(1, 2);

            Console.WriteLine("继续做别的事情。。。");

            Console.WriteLine(result);
            Console.ReadKey();
        }
        
}
同步调用会阻塞线程,如果是要调用一项繁重的工作(如大量IO操作),可能会让程序停顿很长时间,造成糟糕的用户体验,这时候异步调用就很有必要了。

异步调用

异步调用不阻塞线程,而是把调用塞到线程池中,程序主线程或UI线程可以继续执行。
委托的异步调用通过BeginInvoke和EndInvoke来实现。

public class 异步调用
{
        static void Main()
        {
            Console.WriteLine("===== 异步调用 AsyncInvokeTest =====");
            AddHandler handler = new AddHandler(加法类.Add);

            //IAsyncResult: 异步操作接口(interface)
            //BeginInvoke: 委托(delegate)的一个异步方法的开始
            IAsyncResult result = handler.BeginInvoke(1, 2, null, null);

            Console.WriteLine("继续做别的事情。。。");

            //异步操作返回
            Console.WriteLine(handler.EndInvoke(result));
            Console.ReadKey();
        }
        
}
可以看到,主线程并没有等待,而是直接向下运行了。
但是问题依然存在,当主线程运行到EndInvoke时,如果这时调用没有结束(这种情况很可能出现),这时为了等待调用结果,线程依旧会被阻塞。

posted @ 2019-03-21 21:03  人生迷途  阅读(3692)  评论(0编辑  收藏  举报