[C#学习笔记之异步编程模式1]了解同步与异步

C# 异步编程模式详解 C# 异步编程模式是一种强大的编程范式,它允许开发者在处理耗时操作时保持应用程序的响应性。通过 async 和 await 关键字,以及各种异步编程模式和框架,C# 提供了丰富的工具来简化异步编程的实现和维护。在实际应用中,异步编程可以显著提高应用程序的性能和用户体验,特别是在处理 I/O 密集型任务时。因此,掌握 C# 异步编程模式对于现代软件开发来说是非常有价值的。 阅读详情

同步执行

程序执行的流程是按照语句顺序执行,一句执行完再执行下一句,如果遇到函数调用,要等到函数调用返回以后才会执行下一句——这就是“程序的同步执行模式”。

例 1:

using System.Threading;
using System;

public class SynchroPattern
{
    public delegate int NewTaskDelegate(int x);

    public static int NewTask(int x)
    {
        Thread.Sleep(5000);//此处模拟长时间执行的任务
        return x + x;
    }
    public static void Main(string[] args)
    {
        NewTaskDelegate task = NewTask;

        //同步执行
        int syncResult = task(10);
        Console.WriteLine("Sync Proccessing operation...");//这一行只有SyncMethod完成以后才能显示
        Console.WriteLine("Sync Result is: {0}", syncResult);
    }
}

当程序执行到 int syncResult = task(10); 的时候,主线程将等待至少5秒的时间(NewTask方法的执行),才能执行后面的代码,也即在期间,应用程序没有响应,不能执行其他的任何操作,直到NewTask方法返回结果。


例 2:

计算输入的文件夹的容量

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace CalculateFolderSizeNoAsync
{
    class Program
    {
        //定义一个委托
        public delegate long CalculateFolderSizeDelegate(string FolderName);

        //计算指定文件夹的总容量
        private static long CalculateFolderSize(string FolderName)
        {
            if (Directory.Exists(FolderName) == false)
            {
                throw new DirectoryNotFoundException("文件夹不存在");
            }
            DirectoryInfo RootDir = new DirectoryInfo(FolderName);
            //获取所有的子文件夹
            DirectoryInfo[] ChildDirs = RootDir.GetDirectories();
            //获取当前文件夹中的所有文件
            FileInfo[] files = RootDir.GetFiles();
            long totalSize = 0;
            //累加每个文件的大小
            foreach (FileInfo file in files)
            {
                totalSize += file.Length;
            }
            //对每个文件夹执行同样的计算过程:累加其下每个文件的大小
            //这是通过递归调用实现的
            foreach (DirectoryInfo dir in ChildDirs)
            {
                totalSize += CalculateFolderSize(dir.FullName);
            }
            //返回文件夹的总容量
            return totalSize;
        }

        static void Main(string[] args)
        {
            long size;
            string FolderName;
            CalculateFolderSizeDelegate task = CalculateFolderSize;
            Console.WriteLine("请输入文件夹名称(例如:C:\\Windows):");
            FolderName = Console.ReadLine();                          
            size = task(FolderName);
            Console.WriteLine("\n文件夹{0}的容量为:{1}字节", FolderName , size);
        }
    }
}
同样,在CalculateFolderSize执行结束之前,无法执行其后的任何语句!

异步执行

如果计算机在调用函数时,并不需要函数调用结束就继续执行后面的语句,而采用回调的方式处理函数调用,计算机就进入了“程序的异步调用模式”。

我们对例1进行稍微的修改:

using System.Threading;
using System;

public class AsynchroPattern
{
    public delegate int NewTaskDelegate(int x);

    public static int NewTask(int x)
    {
        Thread.Sleep(5000);//此处模拟长时间执行的任务
        return x + x;
    }
    public static void Main(string[] args)
    {
        NewTaskDelegate task = NewTask;
        //通过委托异步调用静态方法NewTask,不是在当前线程调用,而是在另外一个线程调用
        IAsyncResult ret = task.BeginInvoke(10, null, null);
        Console.WriteLine("正在计算中,请耐心等待……"); //即使NewTask方法没有执行结束本行语句也会执行
        int syncResult = task.EndInvoke(ret);  //阻塞,等到调用完成,取出结果
        Console.WriteLine("Sync Result is: {0}", syncResult);
    }
}
注意: 

1.当使用BeginInvoke异步调用方法时,如果方法未执行完,EndInvoke方法就会一直阻塞,直到被调用的方法执行完毕。

2.在运行上面的程序后,由于newTask方法通过Sleep延迟了5秒,因此,程序直到5秒后才输出最终结果x+x。如果不调用EndInvoke方法,程序会立即退出,这是由于使用BeginInvoke创建的线程都是后台线程,这种线程一但所有的前台线程都退出后(其中主线程就是一个前台线程),不管后台线程是否执行完毕,都会结束线程,并退出程序。

同样,对例2修改后的异步执行代码:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;


namespace AsyncCalculateFolderSize1
{
    class Program
    {
        //计算指定文件夹的总容量
        private static long CalculateFolderSize(string FolderName)
        {
            if (Directory.Exists(FolderName) == false)
            {
                throw new DirectoryNotFoundException("文件夹不存在");
            }

            DirectoryInfo RootDir = new DirectoryInfo(FolderName);
            
            //获取所有的子文件夹
            DirectoryInfo[] ChildDirs = RootDir.GetDirectories();
            //获取当前文件夹中的所有文件
            FileInfo[] files = RootDir.GetFiles();
            long totalSize = 0;
            //累加每个文件的大小
            foreach (FileInfo file in files)
            {
                totalSize += file.Length;
            }
            //对每个文件夹执行同样的计算过程:累加其下每个文件的大小
            //这是通过递归调用实现的
            foreach (DirectoryInfo dir in ChildDirs)
            {
                totalSize += CalculateFolderSize(dir.FullName);
            }
            //返回文件夹的总容量
            return totalSize;
        }

        //定义一个委托
        public delegate long CalculateFolderSizeDelegate(string FolderName);

        static void Main(string[] args)
        {

            //定义一个委托变量引用静态方法CalculateFolderSize
            CalculateFolderSizeDelegate d = CalculateFolderSize;
           
            Console.WriteLine("请输入文件夹名称(例如:C:\\Windows):");

            string FolderName = Console.ReadLine();

            //通过委托异步调用静态方法CalculateFolderSize
            IAsyncResult ret=d.BeginInvoke(FolderName,null,null);

            Console.WriteLine("正在计算中,请耐心等待……");
            //阻塞,等到调用完成,取出结果
            long size = d.EndInvoke(ret);
            
            Console.WriteLine("\n计算完成。文件夹{0}的容量为:{1}字节\n", FolderName, size);
        }
    }
}

以上就是同步与异步原理上的简单差别:是否在同一个线程中执行不同的方法,当然通过这两个例子还看不到同步与异步的本质区别,这需要对异步机制进行更加深入的学习!

Socket网络同步异步编程+邮件发送代码+TCP/IP原理解析 第一章发送邮件所需要学习的类 需要引用的命名空间:System.Net.Mail 此命名空间包含了将电子邮件发送到简单邮件的传输协议(SMTP)服务器进行传送的类。 该命名空间中的类: 1)MailMessage类:代表的是可以使用SmtpClient类发送的电子邮件,主要用于设置发送电子邮件时,收件人,发件人及邮件内容的一些相关信息。 2)其中SmtpClient类允许应用程序使用简单邮件传 阅读详情

相关推荐

c#线程同步异步编程

通过实例说明c#同步异步的区别,适合于初学者,能够帮助理解同步异步的概念。

(转)C# Hashtable Synchronized vs SyncRoot

摘自:http://www.afugame.com/club/dispbbs.asp?boardid=13&id=5236& page=1&move=nextSynchronized vs SyncRoot 我们知道,在.net的一些集合类型中,譬如Hashtable和ArrayList,都有Synchronized静态方法和SyncRoot实例方法,他们之间有联系吗?我怎...

weixin_30583563的博客 370

socket同步异步编程实例(C#)

MSDN中实例,其中包括同步socket技术和异步socket技术的全部代码。

c#之线程同步浅析(1)-----轻量级同步Interlocked

转载自:http://blog.csdn.net/kkfdsa132/article/details/5474013 在c#里面,实现线程同步方法有很多种。我了解到的至少有8种。这里先讲下,一种比较简单的同步方法-------轻量级同步Interlock。         为什么说它是轻量级呢?因为它仅对整形数据(即int类型,long也行)进行同步。如果你学过操作系统里面的PV操作(即信

游子的博客 1500

volatile关键字的作用(zz)

恐怕比较一下volatile和synchronized的不同是最容易解释清楚的。volatile是变 量修饰符,而synchronized则作用于一段代码或方法;看如下三句get代码: int i1;              int geti1() {return i1;} volatile int i2;  int geti2() {return i2;} int i3;    ...

weixin_33949359的博客 225

synchroized详解

synchronized的一个简单例子 public class TextThread { /** * @param args */ public static void main(String[] args) { // TODO 自动生成方法存根 TxtThread tt = new TxtThread(); ne...

ymy131931的博客 300

C# 同步异步

一、同步 同步概念大家都很熟悉。在异步概念出来之前,我们的代码都是按同步的方式写的。简单来说,就是程序严格按照代码的逻辑次序,一行一行执行。 看一段代码: public static void Main(string[] args) { Console.WriteLine("Syc proccess - start"); Console.WriteLine("Syc proccess - enter Func1"); func1(); Console.WriteLine("

你要明白,任何问题都不是孤立存在的,一定有人曾经遇到过,并且已经有更好的解决办法了,只是我还不知道。我不应该在黑暗中独自前行,去重新发明轮子,也许我的顿悟,只是别人的基本功!我应该要站在巨人的肩膀上,学习更成熟的经验和方法,然后再来解决这个问题 7018

C#异步编程基础入门总结

异步这概念刚开始接触的时候,不是那么容易接受,但是需要用的地方还真的挺多的,刚学习的时候,也很懵逼走了不少弯路,所以这里有必要总结一下。

dotNet全栈开发 2万+

C#  同步异步(概念理解)

C#  同步异步 IO 概念区分 四个相关概念:   同步Synchronous) 异步( Asynchronous) 阻塞( Blocking ) 非阻塞( Nonblocking)   同步异步图解   通俗理解 (易懂) 同步异步 指的是在客户端 同步意味着 客户端提出了一个请求以后,在回应之前只能等待 异步意味着 客户端提出一个请求以后,还可以继续提其他请...

zam183的博客 1万+

C#异步编程(async and await)及异步方法同步调用

1、什么是异步异步操作通常用于执行完成时间可能较长的任务,如打开大文件、连接远程计算机或查询数据库=异步操作在主应用程序线程以外的线程中执行。应用程序调用方法异步执行某个操作时,应用程序可在异步方法执行其任务时继续执行。 2、同步异步的区别 同步Synchronous):在执行某个操作时,应用程序必须等待该操作执行完成后才能继续执行。 异步(Asynchronous):在执行某个操作时,应用程序可在异步操作执行时继续执行。实质:异步操作,启动了新的线程,主线程方法线程并行执行。 3、异步和多线程的

极客神殿 9055

深入了解 C# 异步编程库 AsyncEx

《AsyncEx:提升C#异步编程效率的强大工具》摘要:AsyncEx是由Stephen Cleary开发的开源C#库,专为解决复杂异步编程场景而设计。该库扩展了C#原生async/await模型,提供异步锁(AsyncLock)、异步信号量(AsyncSemaphore)、异步队列(AsyncQueue)等核心功能,有效应对任务并发控制、资源同步等常见挑战。通过避免线程阻塞、防止死锁、简化异步事件处理,AsyncEx显著提升代码清晰度可维护性,同时增强系统并发性能。其简洁API设计便于集成,已成为处理高

net core ,前端 ,python 全栈开发 1186

C# 异步编程

C#异步编程

qq_33218137的博客 5579

C#使用多线程并发之异步委托IAsyncResult

使用委托开启多线程(多线程深入)1、用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程 BeginInvoke方法可以使用线程异步地执行委托所指向的方法。然后通过EndInvoke方法获得方法的返回值(EndInvoke方法的返回值就是被调用方法的返回值),或是确定方法已经被成功调用。 class Program { private delegate int New

qq_34057374的博客 6877
上一篇: C#内存映射文件学习
下一篇: [C#学习笔记之异步编程模式2]BeginInvoke和EndInvoke方法
然鸟
博客等级 码龄18年 86粉丝 58原创
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值