版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
10的时候被实现的。在本章中概念题目比较多,重点覆盖了.NET中多线程编程方面的面试情况下执行一些耗时的操作。同样,.NET框架下也提供了控制线机制,始介绍.NET多线程编程方面的面试题。面试题 如何在程序中控制.NET的线.NET对象和控件的使用方法和运行原理,本小节重点说明如何在程序中控制.NET的线。.NET在.NET框架为每个进程提供了一个线,一个线有若干个等待操作CLR管理,程序员不需要通过程序去管理线程,这样程序员就可以集中精力处理程序下面的示例使用.NETFramework线计算20和40之间的任意10个数的FCalculate结果。FCalculate结果都FCalculate类表示,该类提供一种名ThreadPoolCallback()的FCalculate值的对象,ThreadPoolCallback()方法将传递给QueueUserWorkItem,它分配池中的一个可用线程来执行此方法。由于为每个FCalculate对象都提供了一个随机值来进行计算,而且每个线程都将占用处理器时间,因此无法提前知道10个结果全部计算出来所需的时间。这就是为何会在构造期间为每个FCalculate对象传递ManualResetEvent类的一个实例的原因。请参考以下示例代码publicpublicclass{//ManualResetEvent类表示一个本地等待处 ,在已 publicFCalculate(intn,ManualResetEvent{_n=_doneEvent=}publicvoidThreadPoolCallback(Object {intthreadIndex= ine("thread{0}started...",_fibOfN= ine("thread0返回计算结果 }publicintCalculate(int {if(n<={return}returnCalculate(n1Calculate(n2返回计算结} publicintN{get{return_n;}}privateint_n;publicintFibOfN{get{return_fibOfN;}}privateint_fibOfN;privateManualResetEvent}10个FCalculate对象全部计算出了结果,然后Main()方法将显示每个FCalculate结果。publicpublicclass{staticvoid{constintFCalculateCalculations= ManualResetEvent[]doneEvents=newManualResetEvent[FcalculateFCalculatefibArraynewFCalculate[FCalculateCalculations];Randomr=newRandom(); ine("launching{0}tasks...",FCalculatefor(inti=0;i<FCalculateCalculations;{doneEvents[i]=newFCalculateFCalculatef=newFCalculate(r.Next(20,40),doneEvents[i]);fibArray[i]=f;} ine("Allcalculationsareforinti0i<FCalculateCalculations {FCalculatef= ine("FCalculate({0})={1}",f.N,}}}FCalculate(22)FCalculate(22)=FCalculate(25)=75025FCalculate(32)=FCalculate(36)=FCalculate(32)=FCalculate(26)=121393FCalculate(35)=FCalculate(23)=28657FCalculate(39)=FCalculate(22)=17711况下,执行一些耗时的操作。在.NET环境中,线的控制是通过ThreadPoolCallback()方法将传递给QueueUserWorkItem,并中分配一个可用线程来执行此方法。面试题 C#中如何控制多线程编.NET.NET自动实现。但在一些特殊的场合下,程序员往往希望自己能线程的运行过程。本小节重点将介绍如何手动地多线程。10.110.1Thread常用属性及方 使用Thread类创建线程时,只需提供线程即可。在C#中,线程是通过ThreadStart(delegate)来提供的。可以把ThreadStart简单地理解为一个函数指针,当调用Thread.Start()方法后,线程就开始执行ThreadStart所代表或者所指向的函数。publicpublicclass {publicvoid{while{ }}}publicclass{publicstaticvoid{ DemooDemo=newThreadmThread=newThread(newwhile(!mThread.IsAlive) { }catch{}}}在.NET中,控制多线程编程非常容易,利用.NETThread类封装好的方法和属性可面试题 如何定义线程优先线程优先级的概念在很多技术框架下都有应用,.NET框架也不例外。.NET框架为程.NET系统会为每个线程都分配一个优先级别。.NET线程优先级,是指定一个线程相对于另Normal,而在运行库外创建的线程在进入运行库时,将保留其先前的优先级。可以通过Thread对象的Priority属性来获取和设置其优先级。值,如表10.2所示。10.2System.Collections ThreadAboveNormal优先级的线程之后,在BelowNormal优注意:如果具有较高优先级的线程可以运行,则具有较低优先级的线程将被抢先,并许具有较高优先级的线次执行。如果在给定的优先级上不再有可运行的线下面的示例代码说明了更改线程优先级的结果。创建两个线程,其中1个线程的优先classclass{staticvoid{PriorityDemopriorityDemo=new//ThreadThreadStart委 =newThreadStart(priorityDemo.ThreadThreadtOne=newThread(startDelegate);tOne.Name="tOne";ThreadtTwo=newThread(startDelegate);tTwo.Name="tTwo";tTwo.Priority=ThreadPriority.BelowNormal;priorityDemo.LoopSwitch=}}class{bool{loopSwitch=}publicbool{set{loopSwitch=value;}publicvoid{longthreadCount=0;{}//输出当前调用线程的名称,优先级和threadCount的数值 ine("{0}with{1,11}priority"+"hasacount={2,13}",Thread.CurrentThread.Name,}}注意:一个线程的优先级不影响该线程的状态,该线程的状态在操作系统可以调度该线Running过Thread对象的Priority属性来获取和设置其优先级。面试题 请解释Thread类中的Join()方Thread类中的Join()Thread编程的程序员来说很容易造成。本小节将说明Join()方法的作用。ThreadJoin()staticvoidMain(string[]{ThreadThreadM=new{for(inti=0;i{staticvoidMain(string[]{ThreadThreadM=new{for(inti=0;i{if(i%100000=={}};ThreadThreadSnew {for(inti=0;i{;if(i%100000=={}}for(inti=0;i{if(i%100000=={;}}}10.1运行结由运行结果可以看出,一开始两个线程交替进行。当线程S执行到语句ThreadM.Join()时,线程M入到线程S之前,这时两个线程合并到一起,变为顺序执行,直到执行完线程M中的所有语句,才去执行剩余的语句(输出结果A)。ThreadJoin()方法的作用将两个交替执行的线程合并为顺序执行的线程。比如在S中调用了MJoin()方法,线MS之前,直M执行完毕后,才会继续执行线程S。面试题 请介绍C#中在编程过常常需要程序定时执行某一操作,而不是人工手动干预。为了实现程序的自动化,C#System.Threading.Timer类,通过这个类可以很方便地实现程序的自动功能。本小节将介绍System.Threading.Timer类的作用。System.Threading.Timer类的作用是设置一个定时器,定时执行用户指定的函数,对象TimerCallback负责这个指定函数的传递,它必须在创建Timer对象时就指定,并且不能更改。下面笔者通过一段简单的示例来进一步说明Timer的使用,具体代码如下:classclass{staticvoidMain(string[]{CustomTimertimer=newCustomTimer();while(true){if(CustomTimer.Tcount>{ ine(string.Format("第{0}次调用11Custom}}}}}publicclass{publicstaticintTcount=publicstaticSystem.Threading.Timertimer;staticCustomTimer(){timer=newSystem.Threading.Timer(TimerCallBack,null,0,}privatestaticvoidTimerCallBack(object{ Tcount=10; }}System.Threading.TimerSystem.Threading.Timertimer=newSystem.Threading.Timer(TimerCallBack,null,0,3000);面试题 如何检索线最大线程数与可用线程认配置。但在一些特殊的场合,程序员可能需要动态地掌握线线程的数量。本小节介线其实就是一个大缓冲池,在C#中的ThreadPool类型提供了许多方法让程序员方便地获取和设置线的上限、下限和当前可用的线程数量。通过调用这些方法,就可以计算出当前线中的线程数已经可用线程数。这些方法如下表10.3所示。10.3ThreadPool 下面的示例代码演示了如何检查线中的最大线程数和可用线程数。通过调用GetAvailableThreads()和GetMaxThreads()方法计算出当前写入操作线中的最大线程数[assembly:FileIOPermissionAttribute(SecurityAction.RequestMinimum,All=@"C:\Demo1@##.dat")][assembly:FileIOPermissionAttribute(SecurityAction.RequestMinimum,All=@"C:\Demo2@##.dat")]class{staticvoid{AutoResetEventmEVent=newAutoResetEvent(false);intworkerThreads;int ThreadPool.GetMaxThreads(outworkerThreads,outportThreads); ine("\n最大工作线程:\t{0}"+"\n最大完成端口线程:{1}",workerThreadsportThreads);//检索由GetMaxThreads()方法返回的最大线 ThreadPool.GetAvailableThreads(outworkerThreads,outportThreads); ine("\n可用工作线程t{0"\n可用完成端口线程:{1}\n",workerThreads,portThreads); newWaitCallback(ThreadPoolDemo.WorkItemMethod), mEVent.WaitOne(5000,}}classState{public publicAutoResetEvent publicState(FileStreamfStream,AutoResetEvent{ =fStream;this.autoEvent=autoEvent;}}class{publicstaticvoidWorkItemMethod(object{ AutoResetEventautoEvent=newconstintArraySize= constintBufferSize= byte[]byteArray=newByte[ArraySize];newRandom().NextBytes(byteArray);FileStreamFWriter1newFileStream(@"C:\Demo1@##.dat",FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite,BufferSize,true);FileStreamFWriter2newFileStream(@"C:\Demo2@##.dat",FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite,BufferSize,true);StatestateInfo1=newState(FWriter1,StatestateInfo2=newState(FWriter2,FWriter1.BeginWrite(byteArray,0,byteArray.Length,newAsyncCallback(EndWriteCallback),stateInfo1);FWriter2.BeginWrite(byteArray,0,byteArray.Length,newAsyncCallback(EndWriteCallback),stateInfo2);//异步写文件 ine("\n完成结束任务\n"); }staticvoidEndWriteCallback(IAsyncResult{ ////获取定义State对象,它限定或包含关于异步操作的信息StatestateInfoState)asyncResult.AsyncState;intworkerThreads;intportThreads;{//检索由GetMaxThreads()方法返回的最大线 ThreadPool.GetAvailableThreads(outworkerThreads,outportThreads); ine("\n可用线程\t{0"\n可用完成端口线程:{1}\n",workerThreads,portThreads); }{ }}}方法与GetAvailableThreads()方法计算出当前线的最大线程数与可用线程数。面试题 多线程编如何控制好多个线程相互之间的联System.Threading命名空间中的MutexMutex的突出特点是可以跨应用程序域边界对资源进行独占,即可以用于同步不同进其实互斥操作在日常生活中随处可见,例如,将Mutex类看作火车票的窗口,乘Mutex对象的关系也正是如此,线程使用想要获取这个Mutex对象的线程都只有等待。class{staticMutexm1;staticMutexstaticAutoResetEventmyEvent1=newAutoResetEvent(false);staticAutoResetEventmyEvent2=newAutoResetEvent(false);staticAutoResetEventmyEvent3=newAutoResetEvent(false);staticAutoResetEventmyEvent4=newAutoResetEvent(false);publicstaticvoidMain(String[]args){ m2newMutex(trueMutex对AutoResetEvent[]evs=newevs[0 //为后面的线th1th2th3th4定义evs[1]=myEvent2;evs[2]=myEvent3;evs[3]=myEvent4;MyThreadMutextm=newThreadth1=newThread(newThreadStart(tm.th1Start));Threadth2=newThread(newThreadStart(tm.th2Start));Threadth3=newThread(newThreadStart(tm.th3Start));Threadth4=newThread(newThreadStart(tm.th4Start));th1.Start();//使用Mutex.WaitAll()方法等待一个Mutex数组中的对象全th3.Start();//使用Mutex.WaitAny()Mutex数组中任意一个 //线程th1、th4结束条件满足 //等待所有4个线程结束}publicvoid{ Mutex[]gMs=newgMs[0m1创建Mutex数组作Mutex.WaitAll()方法的参数gMs[1]=m2; ine("线程结束,将myEvent1设置为有信号状态"); //线程结束,将myEvent1设置为有信号状态}}publicvoid{ //等待m1的释放 ine("线程结束,将myEvent2设置为有信号状态"); //线程结束,将myEvent2设置为有信号状}publicvoid{…}publicvoid{…}}在C#中,使用Mutex对象可以保护共享资源不被多个线程或进程同时,即互斥码之前等待Mutex对象的所属权。当写入共享内存后,线程将释放该Mutex对象。面试题 怎样创建线程独享的全局数线程本地静态变量会带来一些麻烦。针对这个问题,需要用到TLS的概念。可以使用托管线程本地区某一线程和应用程序域所独有的数据。.NETAttributeCLR,它标记的静态字段的存取是依赖当前线程,而独立于其他线classclass{[ThreadStaticstaticpublicstringthreadvalue;//指示静态字段的值对于}然后线程2设置它为world,最后线程1它的时候,得到的是o。问,无须MyClass的实例。的System.Threading.Thread对象也不能够。它的对象则不被ThreadStatic控制。MContext是基于名称的,可以根据名称不同的数据,而ThreadStatic不会一条线。而线程静态字段是不会被的。System.Web.HttpContext.Current是用MContext实现的。publicclassConnHolder:{boolcreatebyme=false;publicConnHolder(){ {threadconn=newSqlConnection(Config.ConnectionString);}}publicSqlConnection{{SqlConnection{}return}}publicvoid {释放threadconn资源,直接返回。否则,释放threadconn资源{ }{ }}}放using(ConnHolderch=new{{mand…}}注意:对于ThreadStatic特性的字段,.NET保证其本身是线程的的机制。.NET提供了ThreadStatic的特性来线程独享的数据。面试题 如何使用流类.NET处理一个文件时,打开文件,文件中的字节流,再关闭文件等操作。本质上都需要通的流类型有文件流、终端操作流、网络Socket等。在.NET中,System.IO.Stream类型是所有流的抽象基类。一般来说,因为Stream类StreamStream类的派生类。当程序员需要自定义一种流类型时,也应该直接或者间接继承自Stream类型。.NET提供了丰富的内建的流类型,其中包括了操作文件的FileStream,操作内存的MemoryStream,操作网络的NetworkStream等。以下示例代码以MemoryStream为例,介绍了流的使MemoryStream类封装一个字节数组,这时是无法调整数组的长度的,在构对MemoryStream类中数据流进行时,为了方便定位器的当前位置,通常使用seek()方法。可以通过指定长度的数组,指定长度的数据。ReadByte()UnicodeEncodingUnicodeUTF-16编码的相关功能。通过其中的方usingusingusingusingSystem.Text;usingSystem.IO;{class{staticvoidMain(string[]{intbyte[]bArray=getData();char[]cArray;UnicodeEncodingMyUnionCode=newMemoryStreammStream=newMemoryStream(bArray);count=0; mStream.Length.ToString(),mStream.Position.ToString());mStream.Seek(0,SeekOrigin.Begin);bArraynew 前10个字count=mStream.Read(bArray,0,while(count<mStream.Length)//逐 {bArray[count++]=}cArray=newchar[MyUnionCode.GetCharCount(bArray,0, MyUnionCode.GetChars(bArray,0,count,cArray,0); }privatestaticbyte {UnicodeEncodingMyUnionCode=newbyte[resultMyUnionCode.GetBytes("C#demo");returnresult;}}}注意:StreamIDisposeable语句,以确保Dispose()方法被正确列。.NETFileStream、NetworkStream、MemoryStream等。当程序员需面试题 Serializable特性如何实现对象实例的序列技术,就是本小节向读者介绍的序列化技术。.NET包含类型的成员变量、类型的名称以及对象所在的程序集等信息。在.NET框架中,通过Serializable特性提供了序列化对象实例的机制。当一个类型被为Serializable后,它就能被诸如BinaryFormatter等实现了IFormatter接口的类型对象进行序列化和反序列化。注意:在面向对象的环境中实现序列化机制时,必须在易用性和灵活性之间进publicclass{privateintOrderID;privatestringOrderName;publicMySerialObject(inti,string{OrderID=i;OrderName=s;}}在.NET框架中,可以通过Serializable特性来使类的对象可以被序列化,同时,列化。以下示例代码展示了Serializable和NonSerialized特性的使用方法。usingSystem;usingusingSystem;usingSystem.IO;usingnamespaceMyConsole{class{staticvoidMain(string[]{ Byte[]data=Serialize(mSerial); MySerialObjectdSerial=DSerialize(data); }}staticByte[]Serialize(MySerialObject{IFormatterformatternewBinaryFormatterusing(MemoryStreamms=new{returnms.ToArray();}}staticMySerialObjectDSerialize(Byte[]{IFormatterf=newusing(MemoryStreamms=new{return}}}publicclass{privateintn1;privatestringpublicMySerialObject(inti,strings){n1=i;customStr=s;}publicoverridestring {return整数:n1.ToStringr\n字符串:}}}在示例代码中,演示了Serializable和NonSerializable的特性应用。此例中使用了BinaryFormatterMySerialObject的一个对象实例进行了序列化和反序列化。下面是程序CustomSerializable的执行结果。n1customStr成员由于NonSerializable的作用而丢失了实上,必须为每个子类都添加Serializable特性来保证子类被序列化。序列化是指将对象实例的状态到区的过程。在此过,先将对象的公过为类型添加Serialization特性,可以使类对象为可被序列化。面试题 .NET中可进行序列化操作的类型有哪面小节中读者已经理解了如何将一个类型为可序列化的类型,但具体完成序二进制序列化(BinaryXML序列化(XML.NET框架提供两种格式的序列化:二进制序列化和XML序列失原来的类型数据。对象使用二进制序列化分解之后,可以被传送至各种媒XML序列化:将对象分解成为XML格式,使用SOAP标准来。由于XML与SOAP是开放标准,因此特别适用于对象需要网络传送的情形。与二进制.NET框架针对两种不同格式的序列化技术,均提供了3BinaryFormatter、SoapFormatterXmlSerializer类。将对象序列化成二进制字节流(Serialize通常使用 ,它可以将二进制字节流还原成原对象(Deserialize注意:XmlSerializer不能用于序列化任何实现了IDictionaryHashtable(散列表),而SoapFormatter和BinaryFormatter却没有这个限制以下示例代码展示了SoapFormatter和XmlSerilizer类型的使用方法,首先需要定义一个publicclass{privateintn1;privatestringpublicstring
publicMySerialObject(inti,string{{n1=i;customStr=s;xmlStr=s;}publicoverridestring{return整数:n1.ToStringr\n字符串:}}SoapFormatterXmlSerilizer类型进行序列化和反序列化的方publicclass{publicstaticByte[]SoapFormatterSerialize(MySerialObject{using(MemoryStreamms=new{//SOAP格式将对象序列化和反SoapFormattersf=newsf.Serialize(ms,obj); returnms.ToArray();}}publicstaticMySerialObjectSoapFormatterDeserialize(Byte[]{using(MemoryStreamms=new{SoapFormattersf=newreturn }}publicstaticByte[]XmlSerializerSerialize(MySerialObject{using(MemoryStreamms=new{XmlSerializerxs=newxs.Serialize(ms,obj);returnms.ToArray();}}publicstaticMySerialObjectXmlSerializerDeserialize(Byte[]{using(MemoryStreamms=new{XmlSerializerxsnewXmlSerializer(typeof(MySerialObject));return(MySerialObject)xs.Deserialize(ms);//反序列化XML文档}}}classclass{staticvoidMain(string[]{MySerialObjectmSerial=newMySerialObject(14,"这是测试字符串"); BytedataMySerialize.SoapFormatterSerialize(mSerial); ine("SoapFormatter序列化后:"); Bytedata1MySerialize.XmlSerializerSerialize(mSerial); ine("XmlSerializer序列化后:"); }}SoapFormatterXmlSerializer序列化后的效果和使用方法。程序的执行结果如图10.2所示。10.2运行结注意:对于XmlSerializer来说,MySerialObject的私有成员和了XmlIgnore特性的.NETXML序列化。.NET框架针对两种不同格式的序列化技术,均提供了相应的可执行序列化和反序列化操作的类型,即BinaryFormatter、SoapFormatter和XmlSerializer。面试题 C#中如何自定义实现序列化和反序列GetObjectData()需要在程序中继承ISerializable接口,并且实现GetObjectData()方法。注意:ISerializable接口,则派生类型需要实现反序列化构造方法,并且重写基类中的GetObjectData()方法。GetObjectData()和自定义的构造方法都可以接收两个参数(SerializationInfoStreamingContext),SerializationInfo类型StreamingContext参数,判断是否需publicclassInsect:{privatestringname_value;privateintID_value;publicstringName{get{returnname_value;}set{name_value=value;}}publicint{get{returnID_value;}set{ID_value=value;}}publicInsect(){ protectedInsect(SerializationInfoinfo,StreamingContext{if(info==thrownewname_value=(string)info.GetValue("AltName",typeof(string));ID_value=(int)info.GetValue("AltID",typeof(int));}}Flags=//publicvirtualvoidGetObjectData(SerializationInfoinfo,StreamingContextcontext){if(info==thrownewSystem.ArgumentNullException("info");info.AddValue("AltName","JamesXLin"); info.AddValue("AltID",9999);}}SecurityPermission(,Execution=true)]namespace{class{publicstaticvoid{{BinaryFormatterbinaryFmt=newInsectp=newInsect();p.IdNumber=100;p.Name=FileStreamfs=newFileStream("Insect.xml",FileMode. ine("最初的名称0最初ID号1}"p.Name,fs=newFileStream("Insect.xml",FileMode.OpenOrCreate);Insectp2=(Insect)binaryFmt.Deserialize(fs); ine("新名称{0ID号1p2.Namep2.Id}catch(Exception{ine("{0}:{1}",exc.Message,}{ }}}}新名称JamesXLinID号:999请按下Enter键,退出系统。列化,而通过添加带有SerializationInfo和StreamingContext的参数的构造方法,可以自定异常不能单等同程序的BUG。BUG是程序设计或实现过的缺陷,在程序中的UG是必须要杜绝的。但异常存在于所有的程序中,并且它是可控制的。只有安全有效地控制程序中的异常,才能使编写的程序代码健壮稳定。当然,如果程序中的异常处理UG.ET调试程序与日志记录是程序开发中不可缺少的一个部分。特别是在程序的过程NET面试题 如何捕获C#程序中的异Exception将跳转到finally块,也就是进入第(4)步。publicpublicvoid{{…}这个异常*/catch(ArgumentNullException{ }catch(ArithmeticException{ } {…}}10.4C#中catch块中的Exception类 发送消息给程序最终使用者。在C#中,异常捕捉由try块和catch块组成,针对try块可以相对应一个或多个catch块,并且每个catch块可以针对特别的异常进行特别处理。面试题 C#中如何自定义异它不是由公共语言运行库,而是由用户程序。程序员可以根据需要,从ApplicationException类派生创建自定义的异常类。ApplicationException4个构造函数。当创建自定义的异常类时,可以依据不同的ApplicationException4publicclassMyCustomException{publicMyCustomExceptionbase 初始化{…}publicpublicMyCustomException(strings):base(s{…}publicMyCustomException(strings,Exceptione):base(s,e{…}的内部异常来初始化ApplicationException实例cxt):base(info,cxt{…}}{…}catch(MyCustomExceptionex){ }调用自定义异常。笔者强烈建议程序员在程序设计中,一定要加入自定义异常类模块的设计。在C#中,自定义异常类可以通过继承ApplicationException类来实现。Application面试题 怎样避免类型转换时的异try/catchint类型转换string类型。但有一些情况则是带有尝试性的string类型转换成int类型,如果这样的尝试性转换开始执行,程序员就应该做好捕捉异常的准备。以下的{inta=6;stringb="";b=a.ToString();intc;stringd="thisistest";c=int.Parse(d);}catch(Exception{ }块做一些尝试性的类型转换,这样,代码不会因为转换而造成程序的终止。对于类型个问题,C#asas强制转换的staticstaticvoidMain(string[]{MyBaseb=newMyBase();MySons=newMySon();stringmystring这是string类型 }staticvoidConverToMyFunction(Object {MyBasea=oasMyBase;}注意:as语句可以尝试性地检查对象。如果可以转换成指定对象,则转换后进行;如果不能转换成指定对象,则返回null。在C#中,虽然使用try{}catch{}可以捕获所有的类型转换错误,但是性能却并不好。对于类型的类型转换,一般使用as语句,这样可以提高转换时异常处理的执行效率。面试题 简介C#中的Trace和Debug境与硬件环境)下也可能产生不同的运行错误。针对这些问题,在C#中提供了Trace和Debug类来协助程序员迅速解决问题。读者应该重视本小节的内容。DebugTraceDebugDebug类中影响要发布的产品的性能和代码大小。下面笔者列举一段简单的Debug类的应用。 或调试输出定向到监视调试输出TextWriterTraceListener的侦 //AutoFlush属性设置trueDebug.AutoFlush= 入inta=Debug.Assert(a2代码运行与预期相同侦 ine("a的值是: oWorld.");Debug.Assert(a2代码运行与预期不同");oWorld.ooTrace类提供了一组代码执行情况的方法和属性,但Trace类无法被继承。TraceRelease模式下都能有效地运行。Trace类主要应用在持续某个模块的运行情况,特别//*TextWriterTraceListener对象将 或调试输出定向到TextWriter,监视调试输出TextWriterTraceListener的侦 //AutoFlush属性设置trueTrace.AutoFlush= //可以使用Indent方法属性修改缩进的级//已重载,将有关调试的信息写入Listeners集合中 inta=Trace.Assert(a==2,"代码运行与预期相同"); ine("变量a的值是:"+a.ToString()); oWorld.");Trace.Assert(a!=2,"代码运行与预期不同");oWorld.oWorld.分析上面的示例代码可以发现,TraceDebug类的用法类似,只是在程序的不同TraceDebug类非常相似,都是提供一组帮助调试代码的方法和属性,并且都无面试题 在C#中如何使用EventLog创建自定义日日志管理是程序开发中的很重要的一个环节,C#Windows日志交互的功能。EventLogCreateEventSource()EventLog类
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年度稻米采购合同:供应商资质审核及质量标准
- 2024年度电子商务平台技术研发合同2篇
- 《营销赢思维》课件
- 2024年度股权转让合同标的详细描述及服务内容扩展
- 2024年度区块链技术的连锁便利店加盟协议
- 2024年度出版发行分包合同2篇
- 2024年度城市轨道交通建设劳务分包合同
- 2024年度城市基础设施建设融资合同
- 基本课件教学课件
- 北师大版六年级数学下册全册教案
- 小学信息科技《数据与编码-探索生活中的“编码”》教学设计
- 2024年云网安全应知应会考试题库
- 铁道概论(第八版)佟立本主编
- 大学生心理健康教育(第二版)PPT全套完整教学课件
- 初中人音版八年级上册音乐2.4欣赏总有一天(15张)ppt课件
- 风湿性心脏病二尖瓣狭窄伴关闭不全;全心衰pbl教学
- 结构化研讨方法(精选干货)
- 通信工程资源录入措施
- 人教版英语选择性必修第四册UNIT 4 Sharing中英文对照
- 一整套首席质量官培训教材
- 超级椰子油二乙醇酰胺的合成新工艺
评论
0/150
提交评论