同步执行
程序执行的流程是按照语句顺序执行,一句执行完再执行下一句,如果遇到函数调用,要等到函数调用返回以后才会执行下一句——这就是“程序的同步执行模式”。
例 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);
}
}
}
以上就是同步与异步原理上的简单差别:是否在同一个线程中执行不同的方法,当然通过这两个例子还看不到同步与异步的本质区别,这需要对异步机制进行更加深入的学习!
分享到:
相关推荐
通过实例说明c#中同步和异步的区别,适合于初学者,能够帮助理解同步和异步的概念。
.net dotnet C# Socket 同步,异步 编程实例
C#Socket同步,异步编程实例
C#Udp同步和异步编程源代码,代码中有详细注释,在VS2010平台下正常运行,使用网络调试助手调试通过,注意根据自己的电脑修改IP地址
C# 5.0 异步编程技术,关注C#新的异步编程特性。
基于C#的TCP/IP同步以及异步通信实现方法,我已经把两种方法封装好了,直接调用就可以了,不仅可以实时获取连接的客户端,还可以实时刷新客户端连接,很好用的,如果有什么问题,欢迎联系我!
Socket异步编程源代码与资料 Socket C#通讯
Windows 应用程序编程中常见的一个模式就是,在GUI用户界面下,将耗时的文件和网络处理放入 子线程,以避免用户界面不能响应的问题。在.NET出现以前,创建线 程并监视线程结束,还要更新 界面等工作,即复杂又要手写...
这是我自己写的C#异步编程方式以及简单示例: 包含委托、task、await async 方式来实现异步。
Visual C#学习笔记光盘 简介:本书由浅入深地...本书内容全面,不但适合于没有任何程序语言编程基础而欲直接学习C#技术的初学者,同时也适合于有一定C#开发基础而需要加深对C#核心技术进一步了解和掌握的程序员。
(同步与异步读写)写的比较可以。需要的下载吧。
Microsoft相信分布式应用程序是未来的趋势,即处理过程分布在客户端和服务器上
C# socket同步和异步通信示例,vs2008 有同步的服务器和客户端 有一部的服务器和客户端
C#.net同步异步SOCKET通讯和多线程总结~
学习C#异步编程技巧和实现原理,提升异步编程的质量
异步模式分为3种:异步模式、基于事件的异步模式和基于任务的异步模式(TAP)。TAP是利用关键字async和await实现的,本文将讲解TAP模式。async和await关键字只是编译器的功能。编译器最终会用Task类创建代码。 1、...
C#异步编程官网手册[收集].pdf
我们将在这里进一步讨论一些.NET类,以及他们在多线程编程中扮演的角色和怎么编程。它们是: System.Threading.ThreadPool 类 System.Threading.Timer 类 如果线程的数目并不是很多,而且你想控制每个线程的...
C# Socket异步编程资料的一个打包全集,里面有文档,有源码例子
Socket同步和异步通信,都是用C#语言编写,并且在同一个Winform项目文件下,同步和异步通信,都包含server和client。