Net线程问题解答
.NET面试题完整版(含前、后端及数据库等多个个方面带参考答案)
.NET⾯试题完整版(含前、后端及数据库等多个个⽅⾯带参考答案)⼀。
基础篇1.简述 private、 protected、 public、 internal 修饰符的权限。
private : 私有成员, 在类的内部才可以访问。
protected : 保护成员,该类内部和继承类中可以访问。
public : 公共成员,完全公开,没有访问限制。
internal: 在同⼀命名空间内可以访问。
2 .列举 页⾯之间传递值的⼏种⽅式。
QueryString,Session,Cookies,Application,Server.Transfer。
2.C#中的委托是什么?事件是不是⼀种委托?委托是将⽅法作为参数带⼊另⼀个⽅法,委托可以理解为指向⼀个函数的引⽤,事件是⼀种特殊的委托。
3.堆和栈的区别? 1、栈(操作系统):由操作系统⾃动分配释放 ,存放函数的参数值,局部变量的值等。
其操作⽅式类似于数据结构中的栈; 2、堆(操作系统): ⼀般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配⽅式倒是类似于链表。
5.abstract class和interface有什么区别?1.抽象类可以有构造⽅法,接⼝中不能有构造⽅法。
2.抽象类中可以有普通成员变量,接⼝中没有普通成员变量3.抽象类中可以包含⾮抽象的普通⽅法,接⼝中的所有⽅法必须都是抽象的,不能有⾮抽象的普通⽅法。
4. 抽象类中的抽象⽅法的访问类型可以是public,protected和(默认类型,虽然eclipse下不报错,但应该也不⾏),但接⼝中的抽象⽅法只能是public类型的,并且默认即为public abstract类型。
5. 抽象类中可以包含静态⽅法,接⼝中不能包含静态⽅法6. 抽象类和接⼝中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接⼝中定义的变量只能是public static final类型,并且默认即为public static final类型。
vbnet线程用法 -回复
vbnet线程用法-回复线程用法介绍:一、什么是线程在计算机科学中,线程是计算机程序执行的最小单元。
它是进程中的一个实体,是CPU调度和分派的基本单位。
线程是进程中的一个实体,是可独立运行的一段程序。
与传统进程不同的是,同一个进程中可以有多个线程同时存在,并且共享进程的内存空间和其他资源。
线程有自己的程序计数器、寄存器和栈,但是没有独立的地址空间。
二、中的线程使用是一种基于.NET框架的编程语言,它提供了多种操作线程的方法和类库,方便我们在应用程序中使用多线程来进行并发处理和提高程序性能。
以下是一些中常用的线程使用方法:1. 创建线程在中,我们可以使用Thread类来创建一个新的线程。
通常情况下,我们会使用匿名函数或者委托来指定要在线程中执行的代码。
以下是一个例子:Dim t As New Thread(Sub()' 线程要执行的代码Console.WriteLine("Hello, World!")End Sub)t.Start() ' 启动线程2. 前台线程和后台线程在线程中,可以将线程设置为前台线程或者后台线程。
前台线程是指在应用程序关闭之前必须执行完毕的线程,而后台线程则是指在应用程序关闭时无论是否执行完毕都会结束的线程。
默认情况下,线程是前台线程,我们可以通过设置Thread类的IsBackground属性来将线程设置为后台线程。
例如:Dim t As New Thread(Sub()' 线程要执行的代码Console.WriteLine("Hello, World!")End Sub)t.IsBackground = True ' 将线程设置为后台线程t.Start() ' 启动线程3. 线程休眠在线程中,我们可以使用Thread类的Sleep方法来暂停当前线程的执行一段时间。
Sleep方法接受一个以毫秒为单位的时间参数,表示要休眠的时间长度。
.net处理并发情况的几种方法
.NET处理并发情况的几种方法引言随着互联网的快速发展和用户需求的增加,对于软件系统的并发处理能力提出了更高的要求。
在.NE T开发中,针对并发情况的处理至关重要。
本文将介绍几种在.N E T平台下处理并发情况的方法,以帮助开发者更好地应对并发问题。
1.锁(L o c k i n g)锁是最基本的一种处理并发情况的方法,通过在关键代码段前后加锁来确保在同一时间内只有一个线程能够访问该代码段。
在.NET中,可以使用以下方式实现锁:l o ck(l oc kO bj ec t){//关键代码段}通过将需要保护的关键代码段放在`l oc k`语句块中,并指定一个共享的锁对象`l oc kO bj ec t`,可以实现对该代码段的互斥访问。
2.互斥量(M utex)互斥量是一种操作系统提供的同步原语,可以用于控制多个线程对共享资源的访问。
在.N E T中,可以使用`Mu t ex`类实现互斥量的使用。
p r iv at es ta ti cM ute x mu te x=ne wM ut ex();m u te x.Wa it On e();//获取互斥量t r y{//关键代码段}f i na ll y{m u te x.Re le as eM ute x();//释放互斥量}通过调用`W ai tO ne()`方法获取互斥量,并在关键代码段执行完毕后调用`R el ea se Mu tex()`方法来释放互斥量,可以有效地控制并发访问。
3.信号量(S emaphore)信号量是另一种常见的同步原语,与互斥量不同的是,信号量允许多个线程同时访问共享资源,但要控制同时并发访问的线程数量。
在.N ET 中,可以使用`S em ap h or e`类实现信号量的使用。
p r iv at es ta ti cS ema p ho re se ma ph or e=n e wS em ap ho re(i nit i al Co u n t:3,m ax im um Co unt:3);s e ma ph or e.Wa it One();//获取信号量t r y{//关键代码段}f i na ll y{s e ma ph or e.Re le ase();//释放信号量}通过在创建`Se ma pho r e`对象时指定初始计数器数量和最大计数器数量,并使用`Wa it One()`方法获取信号量,在关键代码段执行完毕后调用`Re le as e()`方法来释放信号量,可以灵活地控制并发访问的线程数量。
C#、.Net经典面试题目及答案
C#、.Net经典面试题目及答案1,请你说说.NET中类和结构的区别?2,答:结构和类具有大体的语法,但是结构受到的限制比类要多。
结构不能申明有默认的构造函数,为结构的副本是又编译器创建和销毁的,所以不需要默认的构造函数和析构函数。
结构是值类型,所以对结构变量所做的改变不会影响其的原值,而类是应用类型,改变其变量的值会改变其原值。
申明结构用Struck关键字,申明类用class关键字,向方法传递结构是时是通过值传递的,而不是通过引用。
与类不同,结构的实例化可以不使用New关键字。
类可以实现接口。
3,死锁的必要条件?怎么克服?答:系统的资源不足,进程的推进的顺序不合适,资源分配不当,一个资源每次只能被一个进程使用,一个资源请求资源时,而此时这个资源已阻塞,对已获得资源不放,进程获得资源时,未使用完前,不能强行剥夺。
3,接口是否可以继承接口?抽象类是否可以实现接口?抽象类是否可以继承实体类?答:接口是可以继承接口的,抽象类是可以实现接口的,抽象类可以继承实体类,但是有个条件,条件是,实体类必须要有明确的构造函数。
4,构造器Constructor是否可以被继承?是否可以被Override?答:Constructor不可以被继承,因此不能被重写(Overriding),但可以被重载(Overloading).5,当一个线程进入一个对象的方法后,其它线程是否可以进入该对象的方法?答:不可以,一个对象的方法只能由一个线程访问。
6,用最有效的方法算出等已8对于几?答:2<<3.7, C#是否可以对内存直接进行操作?答:这个问题比较难回答,也是个很大的问题。
但是可以这样问答。
C#是可以对内存进行直接操作的,虽然很少用到指针,但是C#是可以使用指针的,在用的时候需要在前边加unsafe,,在.net中使用了垃圾回收机制(GC)功能,它替代了程序员,不过在C#中不可以直接使用finalize方法,而是在析构函数中调用基类的finalize()方法。
NET面试题及答案
update Basic_Role set loginInitialPage='' where loginInitialPage is null1.new有几种用法第一种:new Class();第二种:覆盖方法public new XXXX(){}第三种:new 约束指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数。
2.如何把一个array复制到arrayList里foreach( object o in array )arrayList.Add(o);3.datagrid.datasouse可以连接什么数据源[dataset,datatable,dataview]dataset,datatable,dataview , IList4.概述反射和序列化反射:程序集包含模块,而模块包含类型,类型又包含成员。
反射则提供了封装程序集、模块和类型的对象。
您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。
然后,可以调用类型的方法或访问其字段和属性序列化:序列化是将对象转换为容易传输的格式的过程。
例如,可以序列化一个对象,然后使用HTTP 通过Internet 在客户端和服务器之间传输该对象。
在另一端,反序列化将从该流重新构造对象。
5.概述o/r mapping 的原理利用反射,配置将类于数据库表映射6.类成员有( )种可访问形式可访问形式?不懂。
可访问性:public ,protected ,private,internal7.用sealed修饰的类有什么特点sealed 修饰符用于防止从所修饰的类派生出其它类。
如果一个密封类被指定为其他类的基类,则会发生编译时错误。
密封类不能同时为抽象类。
sealed 修饰符主要用于防止非有意的派生,但是它还能促使某些运行时优化。
具体说来,由于密封类永远不会有任何派生类,所以对密封类的实例的虚拟函数成员的调用可以转换为非虚拟调用来处理。
net面试必会6题经典
net面试必会6题经典
当准备面试时,掌握一些经典的面试问题是非常重要的。
以下是一些经典的面试问题,希望能对你有所帮助:
1. 请介绍一下你自己。
这是一个常见的开场问题,面试官希望通过你的回答了解你的背景、教育经历、工作经验和个人特点。
2. 你最擅长的编程语言是什么?并解释一下该语言的优缺点。
这个问题考察了你对编程语言的熟悉程度,以及你对不同编程语言的理解和比较能力。
3. 请解释一下什么是面向对象编程(OOP)?
面向对象编程是一种常见的编程范式,面试官可能会要求你解释OOP的基本概念、特点以及在实际项目中的应用。
4. 什么是RESTful API?它的优点是什么?
RESTful API是一种常见的API设计风格,面试官可能会通过
这个问题考察你对API设计的理解和经验。
5. 请解释一下什么是数据库索引?它的作用是什么?
数据库索引是数据库中常用的性能优化手段,面试官可能会通
过这个问题考察你对数据库优化的理解和经验。
6. 你在团队中遇到过怎样的技术挑战?你是如何解决的?
这个问题考察了你在实际项目中遇到的问题和解决问题的能力,同时也展现了你在团队中的协作和沟通能力。
以上是一些经典的面试问题,希望对你有所帮助。
在准备面试时,除了回答这些问题,还要多多练习,提高自己的表达能力和思
维能力。
祝你面试顺利!。
.NETFramework4.0下的多线程
.NETFramework4.0下的多线程⼀、简介 在4.0之前,多线程只能⽤Thread或者ThreadPool,⽽4.0下提供了功能强⼤的Task处理⽅式,这样免去了程序员⾃⼰维护线程池,⽽且可以申请取消线程等。
所以本⽂主要描述Task的特性。
⼆、Task的优点 操作系统⾃⾝可以实现线程,并且提供了⾮托管的API来创建与管理这些线程。
但是C#是运⾏在CLR上⾯的,为了⽅便的创建与管理线程,CLR对这些API进⾏了封装,通过System.Threading.Tasks.Task公开了这些包装。
在计算机中,创建线程⼗分耗费珍贵的计算机资源,所以Task启动时,不是直接创建⼀个线程。
⽽是从线程池请求⼀个线程。
并且通过对线程的抽象,程序员⼀般和Task打交道就好,这样降低了⾼效管理多线程的复杂度。
三、Task使⽤⽰例。
Task可以获取⼀个返回值,下⾯的程序实现如下功能:利⽤Task启动⼀个新的线程,然后计算3*5的值,并返回。
1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System.Threading.Tasks;5 using System.Text;67 namespace TaskTest8 {9 class Program10 {11 static void Main(string[] args)12 {13 // 定义并启动⼀个线程,计算5乘以3,并返回⼀个int类型的值14 Task<int> task = Task.Factory.StartNew<int>(15 () => { return 5 * 3; });16 // 线程启动并开始执⾏1718 foreach (char busySymbol in Utility.BusySymbols())19 {20 if (task.IsCompleted)21 {22 Console.Write('\b');23 break;24 }25 Console.Write(busySymbol);26 }27 Console.WriteLine();2829 Console.WriteLine(task.Result.ToString());30 // 如果执⾏⾄此仍未完成那个线程,则输出堆栈信息31 System.Diagnostics.Trace.Assert(task.IsCompleted);32 }33 }34 public class Utility35 {36 public static IEnumerable<char> BusySymbols()37 {38 string busySymbols = @"-\|/-\|/";39 int next = 0;40 {41 while (true)42 {43 yield return busySymbols[next];44 next = (++next) % busySymbols.Length;45 yield return '\b';46 }47 }48 }49 }50 }输出结果如下两种:可以看出,第⼀次运⾏如左图。
.net面试题及答案3篇
.net面试题及答案3篇.net面试题及答案11.JIT是什么,它是如何工作的?GC是什么,简述一下GC的工作方式?JIT:Just in time,C#或者是的代码首先被编译为IL存储在本地,当要运行这些代码的时候,CLR对IL进行第二次编译转换成机器码运行。
好处:可移植性,而且IL在加载到内存中时将受到类型安全性方面检查,这实现了更好的安全性和可靠性。
GC:垃圾回收(garbage collection),是根据程序的需要自动分配和回收内存的过程。
垃圾回收器处理的是引用对象,而且只回收堆上的内存。
这意味着假如维持对一个对象的引用,就会阻止GC重用对象使用的内存。
在.NET中,垃圾回收器采用的是mark-and-pact算法。
在一次垃圾回收周期开始的时候,它要识别对象的所有跟引用,根据这个引用可以遍历每个根引用所标识的一个树形结构,并递归确定所有引用指向的对象。
这样一来,垃圾回收器就可以识别所有可达的对象,在执行回收的时候,GC 不是枚举所有访问不到的对象,相反,通过压缩所有相邻的可达的对象来执行垃圾回收。
不可访问的对象就会被覆盖。
垃圾回收的宗旨是提高内存的利用率,它并不是用来清理文件句柄,和数据库连接字符串,端口或者其他有限的资源(终接器finalizer,不能被显示调用,不能传递任何参数,即不能被重载,只有垃圾回收器才能调用终接器,使用Using语句进行确定性终结2.类(class)和结构(struct)的区别是什么?它们对性能有影响吗?01. 值类型与引用类型结构是值类型:值类型在栈上分配地址,所有的基类型都是结构类型,例如:int 对应System.int32 结构,通过使用结构可以创建更多的值类型类是引用类型:引用类型在堆上分配地址堆栈的执行效率要比堆的执行效率高,可是堆栈的资源有限,不适合处理大的逻辑复杂的对象。
所以结构处理作为基类型对待的小对象,而类处理某个商业逻辑因为结构是值类型所以结构之间的赋值可以创建新的结构,而类是引用类型,类之间的赋值只是复制引用注:1.虽然结构与类的'类型不一样,可是他们的基类型都是对象(object),c#中所有类型的基类型都是object2.虽然结构的初始化也使用了New 操作符可是结构对象依然分配在堆栈上而不是堆上,如果不使用“新建”(new),那么在初始化所有字段之前,字段将保持未赋值状态,且对象不可用02.继承性结构:不能从另外一个结构或者类继承,本身也不能被继承,虽然结构没有明确的用sealed声明,可是结构是隐式的sealed .类:完全可扩展的,除非显示的声明sealed 否则类可以继承其他类和接口,自身也能被继承注:虽然结构不能被继承可是结构能够继承接口,方法和类继承接口一样03.内部结构:结构:没有默认的构造函数,但是可以添加构造函数没有析构函数没有abstract 和sealed(因为不能继承)不能有protected 修饰符可以不使用new 初始化在结构中初始化实例字段是错误的类:有默认的构造函数有析构函数可以使用abstract 和sealed 有protected 修饰符必须使用new 初始化.net面试题及答案21.什么是元编程,.NET有哪些元编程的手段和场景?什么是反射?能否举一些反射的常用场景?有人说反射性能较差,您怎么看待这个问题?有什么办法可以提高反射的性能吗?学着做OA的时候,动态加载不同的DataProvider(Oracle和Sqlserver),方便,可以随时替换不用重新编译程序2.委托是什么?匿名方法是什么?在C#3.0中,Lambda表达式是什么?扩展方法是什么?LINQ是什么?您觉得C# 3.0中还有哪些重要的特性,它们带来了什么优势?BCL中哪些类库和这些特性有关?您*时最常用哪些?委托可以把一个方法作为参数代入另一个方法。
.NET面试题解析(07)-多线程编程与线程同步
.NET⾯试题解析(07)-多线程编程与线程同步系列⽂章⽬录地址:关于线程的知识点其实是很多的,⽐如多线程编程、线程上下⽂、异步编程、线程同步构造、GUI的跨线程访问等等,本⽂只是从常见⾯试题的⾓度(也是开发过程中常⽤)去深⼊浅出线程相关的知识。
如果想要系统的学习多线程,没有捷径的,也不要偷懒,还是去看专业书籍的⽐较好。
常见⾯试题⽬:1. 描述线程与进程的区别?2. 为什么GUI不⽀持跨线程访问控件?⼀般如何解决这个问题?3. 简述后台线程和前台线程的区别?4. 说说常⽤的锁,lock是⼀种什么样的锁?5. lock为什么要锁定⼀个参数,可不可锁定⼀个值类型?这个参数有什么要求?6. 多线程和异步有什么关系和区别?7. 线程池的优点有哪些?⼜有哪些不⾜?8. Mutex和lock有何不同?⼀般⽤哪⼀个作为锁使⽤更好?9. 下⾯的代码,调⽤⽅法DeadLockTest(20),是否会引起死锁?并说明理由。
public void DeadLockTest(int i){lock (this) //或者lock⼀个静态object变量{if (i > 10){Console.WriteLine(i--);DeadLockTest(i);}}}10. ⽤双检锁实现⼀个单例模式Singleton。
11.下⾯代码输出结果是什么?为什么?如何改进她?int a = 0;System.Threading.Tasks.Parallel.For(0, 100000, (i) =>{a++;});Console.Write(a);线程基础进程与线程我们运⾏⼀个exe,就是⼀个进程实例,系统中有很多个进程。
每⼀个进程都有⾃⼰的内存地址空间,每个进程相当于⼀个独⽴的边界,有⾃⼰的独占的资源,进程之间不能共享代码和数据空间。
每⼀个进程有⼀个或多个线程,进程内多个线程可以共享所属进程的资源和数据,线程是操作系统调度的基本单元。
.NET面试题汇总(带答案)
.NET⾯试题汇总(带答案)1.维护数据库的完整性、⼀致性、你喜欢⽤触发器还是⾃写业务逻辑?为什么?答:尽可能⽤约束(包括CHECK、主键、唯⼀键、外键、⾮空字段)实现,这种⽅式的效率最好;其次⽤触发器,这种⽅式可以保证⽆论何种业务系统访问数据库都能维持数据库的完整性、⼀致性;最后再考虑⽤⾃写业务逻辑实现,但这种⽅式效率最低、编程最复杂,当为下下之策。
2.什么是事务?什么是锁?答:事务是指⼀个⼯作单元,它包含了⼀组数据操作命令,并且所有的命令作为⼀个整体⼀起向系统提交或撤消请求操作,即这组命令要么都执⾏,要么都不执⾏。
锁是在多⽤户环境中对数据的访问的限制。
SqlServer⾃动锁定特定记录、字段或⽂件,防⽌⽤户访问,以维护数据安全或防⽌并发数据操作问题,锁可以保证事务的完整性和并发性。
3.什么是索引,有什么优点?答:索引象书的⽬录类似,索引使数据库程序⽆需扫描整个表,就可以在其中找到所需要的数据,索引包含了⼀个表中包含值的列表,其中包含了各个值的⾏所存储的位置,索引可以是单个或⼀组列,索引提供的表中数据的逻辑位置,合理划分索引能够⼤⼤提⾼数据库性能。
4.视图是什么?游标是什么?答:视图是⼀种虚拟表,虚拟表具有和物理表相同的功能,可以对虚拟表进⾏增该查操作;视图通常是⼀个或多个表的⾏或列的⼦集;视图的结果更容易理解(修改视图对基表不影响),获取数据更容易(相⽐多表查询更⽅便),限制数据检索(⽐如需要隐藏某些⾏或列),维护更⽅便。
游标对查询出来的结果集作为⼀个单元来有效的处理,游标可以定位在结果集的特定⾏、从结果集的当前位置检索⼀⾏或多⾏、可以对结果集中当前位置进⾏修改、5.什么是存储过程?有什么优点?答:存储过程是⼀组予编译的SQL语句它的优点:1.允许模块化程序设计,就是说只需要创建⼀次过程,以后在程序中就可以调⽤该过程任意次。
2.允许更快执⾏,如果某操作需要执⾏⼤量SQL语句或重复执⾏,存储过程⽐SQL语句执⾏的要快。
ASP.NET常见面试题及答案(130题)
常见面试题及答案(130题)1. 简述 private、 protected、 public、 internal 修饰符的访问权限。
答 . private : 私有成员, 在类的内部才可以访问。
protected : 保护成员,该类内部和继承类中可以访问。
public : 公共成员,完全公开,没有访问限制。
internal: 在同一命名空间内可以访问。
2 .列举 页面之间传递值的几种方式。
答. 1.使用QueryString, 如....?id=1; response. Redirect()....2.使用Session变量3.使用Server.Transfer4.C#中的委托是什么?事件是不是一种委托?答:委托可以把一个方法作为参数代入另一个方法。
委托可以理解为指向一个函数的引用。
是,是一种特殊的委托5.override与重载的区别答:override 与重载的区别。
重载是方法的名称相同。
参数或参数类型不同,进行多次重载以适应不同的需要Override 是进行基类中函数的重写。
为了适应需要。
6.如果在一个B/S结构的系统中需要传递变量值,但是又不能使用Session、Cookie、Application,您有几种方法进行处理?答: this.Server.TransferResponse. Redirect()---QueryString9.描述一下C#中索引器的实现过程,是否只能根据数字进行索引?答:不是。
可以用任意类型。
11.用.net做B/S结构的系统,您是用几层结构来开发,每一层之间的关系以及为什么要这样分层?答:一般为3层数据访问层,业务层,表示层。
数据访问层对数据库进行增删查改。
业务层一般分为二层,业务表观层实现与表示层的沟通,业务规则层实现用户密码的安全等。
表示层为了与用户交互例如用户添加表单。
优点:分工明确,条理清晰,易于调试,而且具有可扩展性。
缺点:增加成本。
13.什么叫应用程序域?答:应用程序域可以理解为一种轻量级进程。
.NET面试题系列(六)多线程
.NET⾯试题系列(六)多线程
1.多线程的三个特性:原⼦性、可见性、有序性
原⼦性:是指⼀个操作是不可中断的。
即使是多个线程⼀起执⾏的时候,⼀个操作⼀旦开始,就不会被其他线程⼲扰。
⽐如,对于⼀个静态全局变量int i,两个线程同时对它赋值,线程A给他赋值为1,线程B给他赋值为-1。
那么不管这两个线程
以何种⽅式。
何种步调⼯作,i的值要么是1,要么是-1.线程A和线程B之间是没有⼲扰的。
这就是原⼦性的⼀个特点,不可被中断。
可见性:是指当⼀个线程修改了某⼀个共享变量的值,其他线程是否能够⽴即知道这个修改。
显然,对于串⾏来说,可见性问题是不存在的。
有序性:在并发时,程序的执⾏可能会出现乱序。
给⼈的直观感觉就是:写在前⾯的代码,会在后⾯执⾏。
有序性问题的原因是因为程序在
执⾏时,可能会进⾏指令重排,重排后的指令与原指令的顺序未必⼀致。
C#.NET面试题汇总系列四:多线程
C#.NET⾯试题汇总系列四:多线程0. 参考⽂档1. 描述线程与进程的区别?线程(Thread)与进程(Process)⼆者都定义了某种边界,不同的是进程定义的是应⽤程序与应⽤程序之间的边界,不同的进程之间不能共享代码和数据空间,⽽线程定义的是代码执⾏堆栈和执⾏上下⽂的边界⼀个进程可以包括若⼲个线程,同时创建多个线程来完成某项任务,便是多线程2. 什么是互斥?当多个线程访问同⼀个全局变量,或者同⼀个资源(⽐如打印机)的时候,需要进⾏线程间的互斥操作来保证访问的安全性3. Task状态机的实现和⼯作机制是什么?CPS全称是Continuation Passing Style,在.NET中,它会⾃动编译为:将所有引⽤的局部变量做成闭包,放到⼀个隐藏的状态机的类中将所有的await展开成⼀个状态号,有⼏个await就有⼏个状态号每次执⾏完⼀个状态,都重复回调状态机的MoveNext⽅法,同时指定下⼀个状态号MoveNext⽅法还需处理线程和异常等问题4. await的作⽤和原理,并说明和GetResult()有什么区别?从状态机的⾓度出发,await的本质是调⽤Task.GetAwaiter()的UnsafeOnCompleted(Action)回调,并指定下⼀个状态号从多线程的⾓度出发,如果await的Task需要在新的线程上执⾏,该状态机的MoveNext()⽅法会⽴即返回,此时,主线程被释放出来了,然后在UnsafeOnCompleted回调的action 指定的线程上下⽂中继续MoveNext()和下⼀个状态的代码⽽相⽐之下,GetResult()就是在当前线程上⽴即等待Task的完成,在Task完成前,当前线程不会释放注意:Task也可能不⼀定在新的线程上执⾏,此时⽤GetResult()或者await就只有会不会创建状态机的区别了5. Task和Thread有区别吗?Task和Thread都能创建⽤多线程的⽅式执⾏代码,但它们有较⼤的区别Task较新,发布于.NET 4.5,能结合新的async/await代码模型写代码,它不⽌能创建新线程,还能使⽤线程池(默认)、单线程等⽅式编程,在UI编程领域,Task还能⾃动返回UI 线程上下⽂,还提供了许多便利API以管理多个Task6. 多线程有什么⽤?发挥多核CPU的优势,防⽌阻塞7. 说说常⽤的锁,lock是⼀种什么样的锁?常⽤的如 SemaphoreSlim、ManualResetEventSlim、Monitor、ReadWriteLockSlimlock是⼀个混合锁,其实质是 Monitor8. lock为什么要锁定⼀个参数(可否为值类型?)参数有什么要求?lock的锁对象要求为⼀个引⽤类型,可以锁定值类型,但值类型会被装箱,每次装箱后的对象都不⼀样,会导致锁定⽆效对于lock锁,锁定的这个对象参数才是关键,这个参数的同步索引块指针会指向⼀个真正的锁(同步块),这个锁(同步块)会被复⽤9. 多线程和异步的区别和联系?多线程是实现异步的主要⽅式之⼀,异步并不等同于多线程实现异步的⽅式还有很多,⽐如利⽤硬件的特性、使⽤进程或纤程等在.NET中就有很多的异步编程⽀持,⽐如很多地⽅都有Begin、End 的⽅法,就是⼀种异步编程⽀持,内部有些是利⽤多线程,有些是利⽤硬件的特性来实现的异步编程10. 线程池的优点和不⾜?优点:减⼩线程创建和销毁的开销,可以复⽤线程,也从⽽减少了线程上下⽂切换的性能损失,在GC回收时,较少的线程更有利于GC的回收效率缺点:线程池⽆法对⼀个线程有更多的精确的控制,如了解其运⾏状态等;不能设置线程的优先级;加⼊到线程池的任务(⽅法)不能有返回值;对于需要长期运⾏的任务就不适合线程池11. Mutex和lock有什么不同?⼀般⽤哪⼀种⽐较好?Mutex是⼀个基于内核模式的互斥锁,⽀持锁的递归调⽤Lock是⼀个混合锁,⼀般建议使⽤Lock更好,因为lock的性能更好12. 如何实现线程间通信?最简单的就是定义静态变量,然后在各个线程之间通过lock来访问或修改变量其次是利⽤线程上下⽂。
c#.net面试题和答案
1.面向对象的思想主要包括什么?2.什么是ASP .net 中的用户控件3.什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS 、CLS 和CLR 分别作何解释?4.列举一下你所了解的XML 技术及其应用5.值类型和引用类型的区别?写出C#的样例代码。
中常用的对象有哪些?分别描述一下。
7.如何理解委托?8.C#中的接口和类有什么异同。
9.。
net 中读写数据库需要用到哪些类?他们的作用10.UDP 连接和TCP 连接的异同。
11.ASP .net 的身份验证方式有哪些?分别是什么原理?12.进程和线程分别怎么理解?13.什么是code-Behind 技术。
14.活动目录的作用。
中读写XML 的类都归属于哪些命名空间?16.解释一下UDDI 、WSDL 的意义及其作用。
17.什么是SOAP ,有哪些应用。
18.如何部署一个ASP .net 页面。
19.如何理解.net 中的垃圾回收机制。
20.常用的调用webservice 方法有哪些?1 继承继承多态多态 封装 2 用户控件. 不会说懂得做不会说懂得做3 装箱和拆箱发生装箱和拆箱发生值类型向引用类型转换,和引用类型向值类型转 重载:同一个函数参数不同同一个函数参数不同 4.xml 可以用来做网页(xslt) xml 可以当作数据库 xml 可以用来保存对象的系列化可以用来保存对象的系列化5值类型,没有什么好说的.引用类型用处是返回两个以上参数的时候比较好用 ref out 我常用的是out 不要先赋值不要先赋值6 我直接用 sqlhelper 了有connection command 还有参数还有参数 7 回调机制比较有用的.在net 中采用了委托.8 接口,是可以多继承,类只有单继承.接口强调了你必须实现,而没有具本实现的方法和虚类有点相似而没有具本实现的方法和虚类有点相似9 dat 9 datareader dataset areader dataset 还有一个不太常用还有一个不太常用10 udp 不要实现什么三次握手. 11 身份验证最常用还是以前的session 方法. form 验证没有用过. 微软的哪个也没有用过微软的哪个也没有用过12 进程简单理解为单个程序吧(按ctrl+alt+del)可以看到的.它至少有一个主线程 .13 代码后置..不懂得讲不懂得讲14 活动目录.. 完全不会完全不会15 syst 15 system.xml (system.io em.xml (system.io 创建目录的时候用)16 这个也是web 服务里的东西.17 soap 简单协议.我只知道.web 服务是基于它之上的服务是基于它之上的18 部置一个页面. 也就是说没有代码是直接写在aspx 中的了.只接放在IIS 的虚拟目录下就行了.当然要 支持支持19 垃圾回收..一般的只要掌握.非托管对象要记得释放资源就行了吧.20 直接在 里面引用就OK 了.它会自己生成一个代理类1. 填空: (1)面向对象的语言具有___继承性、_封装___性、___多态性。
.net面试常见问题
.net面试常见问题1. 什么是.NET?它的优点是什么?.NET是微软公司开发的一个软件开发框架,它提供了很多组件和库,可以用多种语言编写代码,并且可以跨平台。
.NET的优点包括:可扩展性、易维护性、高可靠性、强类型支持、安全性、良好的性能等等。
2. 请解释一下.NET Framework和.NET Core的区别?.NET Framework是微软公司开发的基于Windows操作系统的.NET平台,它有很多集成的类库和工具。
而.NET Core是.NET Framework的一个跨平台版本,可以在Windows、Linux和MacOS操作系统上运行,并且它支持.NET Standard 库,这样可以更容易地编写跨平台的应用程序。
3. 请解释一下.NET中的CLR?CLR是运行.NET应用程序的虚拟机,它可以将IL代码编译成机器代码,并且负责内存管理、垃圾回收、安全等方面的任务。
4. 请解释一下.NET中的BCL?BCL(Base Class Library)是.NET Framework中常用的类库,它包含在System命名空间中的一组类,包括集合、IO、安全、反射、文本处理等方面的类,它们可以通过.NET Framework内置的工具进行使用和管理。
5. 请解释一下.NET中的GAC?GAC(Global Assembly Cache)是.NET Framework中用于管理全局程序集的地方,它可以提供程序集共享、版本控制、安全保护等方面的支持。
6. 什么是反射?在.NET 中如何使用反射?反射是一种动态获取类型信息、调用方法、创建对象等功能的机制。
在.NET中,可以使用System.Reflection命名空间下的API进行反射。
比如,利用反射可以获取一个类型的属性和方法列表,动态创建对象,调用方法等。
7. 什么是LINQ?它的优点和缺点是什么?LINQ(Language Integrated Query)是一种集成在.NET语言(如C#和 )中的查询技术,它可以通过一种类SQL 的语法,直接在程序中对数据进行查询、过滤、排序、分组等操作,同时支持不同数据源的查询(如数据库、XML、集合等)。
.net面试题语雀
.net面试题语雀在面试中,有关.NET的问题通常涉及到以下几个方面,基础知识、面向对象编程、多线程、异常处理、、、Entity Framework、LINQ、Web服务、安全性等。
下面我将从这些方面来回答你的问题。
1. .NET基础知识:.NET是一个由微软开发的跨平台应用程序框架。
它包括了一系列的开发工具和库,用于构建各种类型的应用程序,包括桌面应用、Web应用、移动应用等。
.NET的核心组件是公共语言运行时(CLR),它负责将.NET程序编译成可执行代码并在运行时执行。
2. 面向对象编程:.NET是基于面向对象编程的框架,它支持封装、继承和多态等面向对象的特性。
面向对象编程的优点包括代码重用、可维护性和可扩展性等。
在.NET中,你可以使用C#、等编程语言来实现面向对象编程。
3. 多线程:在.NET中,你可以使用多线程来实现并发编程。
多线程可以提高程序的性能和响应能力。
你可以使用Thread类或者Task类来创建和管理线程。
在多线程编程中,需要注意线程同步和互斥的问题,以避免数据竞争和死锁等问题。
4. 异常处理:异常处理是.NET中重要的编程概念之一。
在程序运行过程中,可能会出现各种异常情况,如空引用异常、数组越界异常等。
你可以使用try-catch语句来捕获和处理异常,以保证程序的稳定性和可靠性。
5. :是.NET中用于构建Web应用程序的技术框架。
它提供了丰富的功能和工具,用于开发Web页面、处理用户请求、访问数据库等。
支持多种编程模型,包括Web Forms、MVC和Web API等。
6. :是.NET中用于访问数据库的技术框架。
它提供了一组类和方法,用于连接数据库、执行SQL语句、处理数据等操作。
支持多种数据库,包括SQL Server、Oracle、MySQL等。
7. Entity Framework:Entity Framework是.NET中的一个对象关系映射(ORM)框架,它简化了对数据库的操作。
网络编程中的常见问题和解决方案
网络编程中的常见问题和解决方案网络编程中常见的问题和解决方案一般分为以下几类:网络通信问题、并发处理问题、性能优化问题、安全问题和扩展性问题。
下面将依次阐述这些问题及常用的解决方案。
一、网络通信问题1.连接问题:网络编程中常常会遇到连接问题,如连接超时、连接中断等。
解决方案包括使用超时设置、重试机制、心跳包检测、断线重连等。
2.数据传输问题:数据传输可能会存在数据丢失、数据传输不完整等问题。
常见的解决方案有使用校验和、分包处理、流控制、确认应答等。
3.网络拥塞问题:当网络负载过大时,可能会出现网络拥塞,导致延迟增加、数据丢失等问题。
解决方案包括使用网络流量控制、拥塞控制算法(如TCP的拥塞窗口算法)、负载均衡等。
二、并发处理问题1.线程安全问题:在多线程环境中,可能会出现资源竞争、死锁等问题。
解决方案包括使用线程同步机制(如互斥锁、条件变量)、使用一致性哈希算法避免缓存穿透等。
2.任务调度问题:在并发场景中,需要考虑任务调度的问题,如任务的优先级、顺序等。
解决方案包括使用线程池、任务队列、优先级队列等。
三、性能优化问题1.网络延迟问题:网络延迟是影响性能的重要因素之一。
解决方案包括使用更快的网络协议、优化网络拓扑、使用CDN等。
2.数据传输效率问题:数据传输效率低会影响整体性能。
解决方案包括使用压缩算法、增量传输等。
3.数据库访问性能问题:大量数据库读写操作可能成为性能瓶颈。
解决方案包括使用数据库连接池、数据缓存、数据库分库分表等。
四、安全问题1.数据加密问题:网络传输中的数据可能会被窃听或篡改。
解决方案包括使用SSL/TLS协议进行加密传输、使用数字证书验证身份等。
2.防止恶意攻击问题:网络编程中需要考虑如何防止恶意攻击,如DDoS攻击、SQL注入等。
解决方案包括使用防火墙、输入验证、限流等。
五、扩展性问题1.系统扩展问题:随着业务发展,系统可能需要扩展为多节点部署。
解决方案包括使用集群、负载均衡、分布式存储等。
.Net常见线程安全问题整理
.Net常见线程安全问题整理最近线上⼜出现了⼏次线程安全问题导致的服务异常,线程安全问题都是隐藏的炸弹,有可能⼏个⽉都不出问题,也有可能连续⼏天爆炸好⼏次,问题出现的结果完全是⽆法确定的,包括但不限于如下结果:1. 应⽤异常,且⽆法⾃恢复,必须重启站点或服务;2. 陷⼊死循环,导致CPU占⽤100%,从⽽整台服务器崩溃;3. 错误数据⼊库,导致⼀系列的排查、数据修复的困难,甚⾄可能⽆法修复数据;因此,很有必要做⼏次全局的筛查,做⼀些特征值搜索和处理,简单梳理了⼀下,凡是符合如下5种特征的代码,都有线程不安全的可能性:1、类的静态变量:public class Iamclass{static Dictionary<string, string> _cache = new Dictionary<string, string>();public static void Operation(){_cache.Add(new Guid().ToString(), "1");// 线程不安全代码}}2、类的静态属性:public class Iamclass{static Dictionary<string, string> Cache {get; set;} = new Dictionary<string, string>();public static void Operation(){Cache.Add(new Guid().ToString(), "1");// 线程不安全代码}}3、单例对象的静态变量:public class XxxService{IIamclass instance = IocHelper.GetSingleInstance<IIamclass>(); // 获取单例}public class Iamclass : IIamclass{Dictionary<string, string> _cache = new Dictionary<string, string>();public void Operation(){_cache.Add(new Guid().ToString(), "1");// 线程不安全代码}}4、单例对象的静态属性:public class XxxService{IIamclass instance = IocHelper.GetSingleInstance<IIamclass>(); // 获取单例}public class Iamclass : IIamclass{Dictionary<string, string> Cache {get; set;} = new Dictionary<string, string>();public void Operation(){Cache.Add(new Guid().ToString(), "1");// 线程不安全代码}}5、多线程共享的局部变量public class XxxService{public void Operation(){var cache = new Dictionary<string, string>();System.Threading.Tasks.Parallel.For(1, 10, idx =>{cache.Add(new Guid().ToString(), "1"); //线程不安全代码});}}列举下处理过的⼏次线程安全问题,都是如下2类问题:1、应⽤错误且⽆法恢复的,通常异常为:索引超出了数组界限:public class MessageService : BaseService{private static Dictionary<string, Timer> _timerDict = new Dictionary<string, Timer>();public async void SendMessageAsync(string msgId, MessageInputDto2 input){var timer = new Timer(60 * 1000) { AutoReset = true };_timerDict[msgId] = timer; // 问题代码timer.Elapsed += (sender, eventArgs) =>{try{/* 具体业务代码 */timer.Stop();timer.Close();_timerDict.Remove(msgId);}catch(Exception exp){// 异常处理代码}}}}解决⽅法,⼀般是加锁注:如果加lock 可能出现瓶颈,要进⾏流程梳理,是否要更换实现⽅案:lock(_timerDict){_timerDict[msgId] = timer; // 问题代码}timer.Elapsed += (sender, eventArgs) =>{try{/* 具体业务代码 */timer.Stop();timer.Close();lock(_timerDict){_timerDict.Remove(msgId);}}catch(Exception exp){// 异常处理代码}}2、陷⼊死循环,导致服务器CPU 100%卡顿问题:有个常见业务,获取⼀串没有使⽤过的随机数或随机字符串,⽐如⽤户⾝份Token,⽐如抽奖等等下⾯是常见的获取不重复的随机数代码,在_rnd.Next 没有加锁,其内部⽅法InternalSample会导致返回结果都是0,从⽽导致while陷⼊死循环:public class CodeService{private static Random _rnd = new Random(Guid.NewGuid().GetHashCode());public static GetCode(){var ret = "";var redis = IocHelper.GetSingleInstance<IRedis>();// 获取⼀个未使⽤过的序号do{ret = _rnd.Next(10000).ToString(); // 问题代码}while(!redis.Add(ret, "", TimeSpan.FromSeconds(3600)));return ret;}}解决⽅法,双重校验:加锁,并判断循环次数:public class CodeService{private static Random _rnd = new Random(Guid.NewGuid().GetHashCode());public static GetCode(){var ret = "";var redis = IocHelper.GetSingleInstance<IRedis>();var maxLoop = 10;// 获取⼀个未使⽤过的序号do{lock(_rnd){ret = _rnd.Next(10000).ToString();}}while(!redis.Add(ret, "", TimeSpan.FromSeconds(3600)) && (maxLoop--) > 0); if(maxLoop <= 0){throw new Exception("10次循环,未找到可⽤数据:" + ret);}return ret;}}https:///youbl/article/details/101693752 转载。
线程安全面试题
线程安全面试题在软件开发中,线程安全是一个重要的概念,特别是在多线程编程的场景下。
线程安全指的是多个线程同时访问共享资源时,不会产生不可预测的结果或者导致不一致的状态。
线程安全的实现必须考虑并发访问的问题,保证程序的正确性和可靠性。
本文将介绍几个与线程安全相关的常见面试题,并给出相应的答案和解析。
1. 什么是线程安全?线程安全是指多个线程同时访问一个共享资源时,不会导致数据的竞态条件(Race Condition)和其他的并发问题,确保程序的正确性和一致性。
2. 如何保证线程安全?实现线程安全的方法有多种,包括但不限于以下几种:- 使用互斥锁(Mutex)来确保同一时间只有一个线程可以访问共享资源。
- 使用信号量(Semaphore)来限制同时访问共享资源的线程数。
- 使用条件变量(Condition Variable)来实现线程之间的通信和协作。
- 使用原子操作(Atomic Operation)来保证特定操作的原子性。
- 使用线程安全的数据结构或者线程安全的库函数。
3. 什么是竞态条件?竞态条件是指多个线程同时访问共享资源时,由于执行的顺序不确定或者时间上的交错,导致程序的输出结果与执行的顺序不一致的情况。
竞态条件可能导致数据错乱、死锁、活锁等问题。
4. 怎样避免竞态条件?为了避免竞态条件,可以采取以下几种策略:- 使用互斥锁(Mutex)来确保同一时间只有一个线程可以访问共享资源。
- 尽量减少共享资源的使用,避免多个线程对同一资源的竞争。
- 使用原子操作(Atomic Operation)来保证特定操作的原子性,避免多个线程同时对同一数据进行读写。
- 合理设计线程间的通信和协作机制,避免死锁和活锁的发生。
5. 什么是死锁和活锁?死锁是指多个线程因为互相等待对方持有的资源而无法继续执行的状态,从而导致整个程序无法正常运行。
活锁是指多个线程在尝试解决冲突时,由于策略不当导致一直重复相同的操作而无法继续执行的状态。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
N e t线程问题解答Company Document number:WTUT-WT88Y-W8BBGB-BWYTT-19998.Net线程问题解答目录••••••••••••••••••••••••••基础篇怎样创建一个线程我只简单列举几种常用的方法,详细可参考一)使用Thread类ThreadStartthreadStart=new ThreadStart(Calculate);2007/09/13ET 应用的线程实际上仍然是Windows线程。
但是,当某个线程被CLR所知时,我们将它称为受托管的线程。
具体来说,由受托管的代码创建出来的线程就是受托管的线程。
如果一个线程由非托管的代码所创建,那么它就是非托管的线程。
不过,一旦该线程执行了受托管的代码它就变成了受托管的线程。
CLR确保每一个受托管的线程在任意时刻都在一个AppDomain中执行,但是这并不代表一个线程将永远处在一个AppDomain中,它可以随着时间的推移转到其他的AppDomain中。
从安全的角度来看,一个受托管的线程的主用户与底层的非托管线程中的Windows主用户是无关的。
前台线程与后台线程后来找到了这个办法:设置线程为后台线程。
?msdn对前台线程和后台线程的解释:托管线程或者是后台线程,或者是前台线程。
后台线程不会使托管执行环境处于活动状态,除此之外,后台线程与前台线程是一样的。
一旦所有前台线程在托管进程(其中 .exe 文件是托管程序集)中被停止,系统将停止所有后台线程并关闭。
通过设置属性,可以将一个线程指定为后台线程或前台线程。
例如,通过将设置为 true,就可以将线程指定为后台线程。
同样,通过将 IsBackground 设置为 false,就可以将线程指定为前台线程。
从非托管代码进入托管执行环境的所有线程都被标记为后台线程。
通过创建并启动新的 Thread 对象而生成的所有线程都是前台线程。
如果要创建希望用来侦听某些活动(如套接字连接)的前台线程,则应将设置为 true,以便进程可以终止。
这样,主线程就是后台线程,在关闭主程序的时候就会关闭主线程,从而关闭所有线程。
但是这样的话,就会强制关闭所有正在执行的线程,所以在关闭的时候要对线程工作的结果保存。
经常看到名为BeginXXX和EndXXX的方法,他们是做什么用的这是的一个异步方法名称规范.Net在设计的时候为异步编程设计了一个异步编程模型(APM),这个模型不仅是使用.NET的开发人员使用,.Net内部也频繁用到,比如所有的Stream就有BeginRead,EndRead,Socket,WebRequet,SqlCommand都运用到了这个模式,一般来讲,调用BegionXXX的时候,一般会启动一个异步过程去执行一个操作,EndEnvoke可以接收这个异步操作的返回,当然如果异步操作在EndEnvoke调用的时候还没有执行完成,EndInvoke会一直等待异步操作完成或者超时.Net的异步编程模型(APM)一般包含BeginXXX,EndXXX,IAsyncResult这三个元素,BeginXXX 方法都要返回一个IAsyncResult,而EndXXX都需要接收一个IAsyncResult作为参数,他们的函数签名模式如下IAsyncResult BeginXXX(...);<返回类型> EndXXX(IAsyncResult ar);BeginXXX和EndXXX中的XXX,一般都对应一个同步的方法,比如FileStream的Read方法是一个同步方法,相应的BeginRead(),EndRead()就是他的异步版本,HttpRequest有GetResponse来同步接收一个响应,也提供了BeginGetResponse和EndGetResponse这个异步版本,而IAsynResult是二者联系的纽带,只有把BeginXXX所返回的IAsyncResult传给对应的EndXXX,EndXXX才知道需要去接收哪个BeginXXX 发起的异步操作的返回值。
这个模式在实际使用时稍显繁琐,虽然原则上我们可以随时调用EndInvoke来获得返回值,并且可以同步多个线程,但是大多数情况下当我们不需要同步很多线程的时候使用回调是更好的选择,在这种情况下三个元素中的IAsynResult就显得多余,我们一不需要用其中的线程完结标志来判断线程是否成功完成(回调的时候线程应该已经完成了),二不需要他来传递数据,因为数据可以写在任何变量里,并且回调时应该已经填充,所以可以看到微软在新的.Net Framework中已经加强了对回调事件的支持,这总模型下,典型的回调程序应该这样写+=new SomeEventHandler(Caculate);+=new SomeEventHandler(callback);();(注:我上面讲的是普遍的用法,然而BeginXXX,EndXXX仅仅是一种模式,而对这个模式的实现完全取决于使用他的开发人员,具体实现的时候你可以使用另外一个线程来实现异步,也可能使用硬件的支持来实现异步,甚至可能根本和异步没有关系(尽管几乎没有人会这样做)-----比如直接在Beginxxx里直接输出一个"Helloworld",如果是这种极端的情况,那么上面说的一切都是废话,所以上面的探讨并不涉及内部实现,只是告诉大家微软的模式,和框架中对这个模式的经典实现)异步和多线程有什么关联有一句话总结的很好:多线程是实现异步的一种手段和工具我们通常把多线程和异步等同起来,实际是一种误解,在实际实现的时候,异步有许多种实现方法,我们可以用进程来做异步,或者使用纤程,或者硬件的一些特性,比如在实现异步IO的时候,可以有下面两个方案:1)可以通过初始化一个子线程,然后在子线程里进行IO,而让主线程顺利往下执行,当子线程执行完毕就回调2)也可以根本不使用新线程,而使用硬件的支持(现在许多硬件都有自己的处理器),来实现完全的异步,这是我们只需要将IO请求告知硬件驱动程序,然后迅速返回,然后等着硬件IO就绪通知我们就可以了实际上DotNet Framework里面就有这样的例子,当我们使用文件流的时候,如果制定文件流属性为同步,则使用BeginRead进行读取时,就是用一个子线程来调用同步的Read方法,而如果指定其为异步,则同样操作时就使用了需要硬件和操作系统支持的所谓IOCP的机制WinForm多线程编程篇我的多线程WinForm程序老是抛出InvalidOperationException ,怎么解决在WinForm中使用多线程时,常常遇到一个问题,当在子线程(非UI线程)中修改一个控件的值:比如修改进度条进度,时会抛出如下错误Cross-thread operation not valid: Control 'XXX' accessed from a thread other than the thread it was created on.在VS2005或者更高版本中,只要不是在控件的创建线程(一般就是指UI主线程)上访问控件的属性就会抛出这个错误,解决方法就是利用控件提供的Invoke和BeginInvoke把调用封送回UI线程,也就是让控件属性修改在UI线程上执行,下面列出会报错的代码和他的修改版本ThreadStartthreadStart=new ThreadStart(Calculate);概ms发现v2003的警告对广大开发者不起作用,所以用了一个比较狠一点的方法.不过问题依然存在:既然这样设计的原因主要是因为控件的值非线程安全,那么DotNet framework中非线程安全的类千千万万,为什么偏偏跨线程修改Control的属性会有这样严格的限制策略呢这个问题我还回答不好,希望博友们能够予以补充有没有什么办法可以简化WinForm多线程的开发使用backgroundworker,使用这个组建可以避免回调时的Invoke和BeginInvoke,并且提供了许多丰富的方法和事件参见,我在这里不再赘诉线程池线程池的作用是什么作用是减小线程创建和销毁的开销创建线程涉及用户模式和内核模式的切换,内存分配,dll通知等一系列过程,线程销毁的步骤也是开销很大的,所以如果应用程序使用了完一个线程,我们能把线程暂时存放起来,以备下次使用,就可以减小这些开销所有进程使用一个共享的线程池,还是每个进程使用独立的线程池每个进程都有一个线程池,一个Process中只能有一个实例,它在各个应用程序域(AppDomain)是共享的,. 中默认线程池的大小为工作线程25个,IO线程1000个,有一个比较普遍的误解是线程池中会有1000个线程等着你去取,其实不然, ThreadPool仅仅保留相当少的线程,保留的线程可以用SetMinThread这个方法来设置,当程序的某个地方需要创建一个线程来完成工作时,而线程池中又没有空闲线程时,线程池就会负责创建这个线程,并且在调用完毕后,不会立刻销毁,而是把他放在池子里,预备下次使用,同时如果线程超过一定时间没有被使用,线程池将会回收线程,所以线程池里存在的线程数实际是个动态的过程为什么不要手动线程池设置最大值当我首次看到线程池的时候,脑袋里的第一个念头就是给他设定一个最大值,然而当我们查看ThreadPool 的SetMaxThreads文档时往往会看到一条警告:不要手动更改线程池的大小,这是为什么呢其实无论FileStream的异步读写,异步发送接受Web请求,甚至使用delegate的beginInvoke都会默认调用 ThreadPool,也就是说不仅你的代码可能使用到线程池,框架内部也可能使用到,更改的后果影响就非常大,特别在iis中,一个应用程序池中的所有 WebApplication会共享一个线程池,对最大值的设定会带来很多意想不到的麻烦线程池的线程为何要分类线程池有一个方法可以让我们看到线程池中可用的线程数量:GetAvaliableThread(out workerThreadCount,out iocompletedThreadCount),对于我来说,第一次看到这个函数的参数时十分困惑,因为我期望这个函数直接返回一个整形,表明还剩多少线程,这个函数居然一次返回了两个变量.原来线程池里的线程按照公用被分成了两大类:工作线程和IO线程,或者IO完成线程,前者用于执行普通的操作,后者专用于异步IO,比如文件和网络请求,注意,分类并不说明两种线程本身有差别,线程就是线程,是一种执行单元,从本质上来讲都是一样的,线程池这样分类,举例来说,就好像某施工工地现在有1000把铁锹,规定其中25把给后勤部门用,其他都给施工部门,施工部门需要大量使用铁锹来挖地基(例子土了点,不过说明问题还是有效的),后勤部门用铁锹也就是铲铲雪,铲铲垃圾,给工人师傅修修临时住房,所以用量不大,显然两个部门的铁锹本身没有区别,但是这样的划分就为管理两个部门的铁锹提供了方便线程池中两种线程分别在什么情况下被使用,二者工作原理有什么不同下面这个例子直接说明了二者的区别,我们用一个流读出一个很大的文件(大一点操作的时间长,便于观察),然后用另一个输出流把所读出的文件的一部分写到磁盘上我们用两种方法创建输出流,分别是创建了一个异步的流(注意构造函数最后那个true)FileStream outputfs=new FileStream(writepath, , , ,256,true);创建了一个同步的流FileStream outputfs = (writepath);然后在写文件期间查看线程池的状况string readpath="e:\\";string writepath="e:\\";byte[]buffer=newbyte[];et实现异步IO是用一个子线程调用fs的同步Write方法来实现的,这时这个子线程会一直阻塞直到调用完成.这个子线程其实就是线程池的一个工作线程,所以我们可以看到,同步流的异步写回调中输出的工作线程数少了一,而使用异步流,在进行异步写时,采用了 IOCP方法,简单说来,就是当BeginWrite执行时,把信息传给硬件驱动程序,然后立即往下执行(注意这里没有额外的线程),而当硬件准备就绪, 就会通知线程池,使用一个IO线程来读取.Net线程池有什么不足没有提供方法控制加入线程池的线程:一旦加入线程池,我们没有办法挂起,终止这些线程,唯一可以做的就是等他自己执行1)不能为线程设置优先级2)一个Process中只能有一个实例,它在各个AppDomain是共享的。