《精通C#》第十七章

进程简单的说就是一个正在运行的程序,包含了运行该程序所需要的一切资源以及内存分配。线程是进程的基本执行单元,在进程的入口点(类似main())创建的第一个线程称之为主线程。只有一个主线程的进程是线程安全的,因为一个程序中的数据只有一个线程在访问,但是只有一个线程的后果就是,如果实在执行一个复杂的操作时,因为运行的时间太长,对用户来说,就好像是请求没被响应一样。所以可以使用CreateThread()之类的Windows API函数另外产生次线程,每一个次线程都拥有与主线程一样的权限,线程之间相互独立,它们可以同时访问共享数据。拥有多线程会给我们带来一种大量的活动几乎在同一时间内完成,但是事实上,同时运行多个线程需要有多个CPU才行。因为实际上CPU将时间分成一个个的时间片(单位时间),按线程优先级分配时间片,当一个线程的时间片用完之后,它就会被挂起,执行下一个线程,由于时间片非常之短,计算机的运行速度有非常之快,故而导致一些操作看起来似乎是在同时发生响应。因而虽然多线程会相对的加快响应速度,但是线程过多的话性能反而会下降,因为CPU需要时间在线程之间进行转换。使用System.Diagnostics命名空间内定义的类,我们就可以使用编程的方式访问进程,

命名空间类名    作用
Process提供了访问本地进程和的远程进程的功能,允许通过编程方式开始或结束进程
ProcessModule  代表一个加载到特定进程的模块(dll或者exe),它能代表任何模块(基于com、基于.Net或基于传统C的二进制程序)
ProcessModuleCollection提供ProcessModule对象的强类型集合
ProcessStartInfo指点通过Process.Start方法启动进程是使用的一组值
ProcessThread代表指定进程中的线程。用于诊断一个进程的线程情况,并不用于在进程中创建线程
ProcessThreadCollection提供ProcessThread对象的强类型集合

 其中Process是比较常用的一个类,它提供了用于启动、关闭进程,设定进程优先级,以及获得进程中活动线程的列表并且加载给定进程的模块,下图是有关Process的一部分关键属性:

属性  作用
ExitTime获取终止进程相关的时间戳
Handle返回操作系统分配给进程的句柄(由IntPtr表示)。当构建与非托管代码交互的.Net程序时,该属性很有用
Id获取关联的进程的ID
MachineName 获取关联进程运行的计算机名
MainWindowTitle获取进程主窗口的标题(如果没有住窗口,则返回空字符串)
Modules可以访问强类型ProcessModuleCollection,后者表示一组加载到当前进程的模块(dll或者exe)
ProcessName获取进程的名称(应用程序本身的名称)
Responding指示进程的用户界面是否响应用户输入(或者当前是否被挂起)
StartTime    获取关联进程开始的时间
Thread  

获取运行在关联进程中的一组线程的设置(由ProcessThread对象的集合表示)

 以下则是该类的一些方法:

方法作用
CloseMainWindow通过向进程的主窗口发送关闭消息来关闭拥有用户界面的进程
GetCurrentProcess这个静态方法返回新的Process对象以表示当前活动的进程
GetProcesses  这个静态方法返回运行在给定计算机上的新的Process对象
Kill  立即停止关联的进程
Start  启动一个进程

在使用GetProcesses()方法返回一个Process对象组的时候,使用”.“符号即表示为本机,静态方法Process.GetProcessById通过关联的PID获取特定的进程,但是若是所指定的PID不存在,就会引发异常,还需要记住的是PID肯定不能为0,因为0是用来表示cpu空闲状态的。当使用Process.Modules属性访问ProcessModuleCollection时,可以列举出承载在进程中的所有模块:基于.Net、基于COM、基于传统C的库。还得说一下,模块这个词用于描绘承载于指定进程中的dll或者exe。在使用Kill方法结束进程的时候要注意该进程是否已经被结束,若是已经被结束了,再使用Kill()时,就会报错。

在.Net平台下,可执行程序会承载在一个进程的逻辑分区内,而非托管的程序是直接承载的,这个逻辑分区被命名为应用程序域,一个进程可以承载多个应用程序域,每个应用程序域之间都是相互隔离的,因此如果不使用分布式编程协议(如WCF),运行在某个应用程序域中的应用程序将无法访问其他应用程序中的任何数据,不论是全局的或是静态的。但是操作系统进程却只能承载默认的应用程序域。.NET平台运行我们使用System.AppDomain类,监控应用程序域、在运行时新建应用程序域、向新的应用程序域加载程序集等多种任务。

方法作用
CreateDomain该静态方法在当前进程中创建一个新的应用程序域
CreateInstance 在加载程序集到调用的应用程序域时,在外部程序集文件中创建指定类型的新实例
EXecuteAssembly根据文件名在应用程序中执行程序集
GetAssemblies 获取已经加载到此应用程序域中的.Net程序集
GetCurrentThreadId  该静态方法返回当前应用程序域上活动的线程Id
Load  动态加载程序集到当前的应用程序域
Unload  该静态方法在进程中卸载指定的应用程序域
属性作用
BaseDirectory获取目录路径,程序集解决程序用它来探测程序集
CurrentDomain该静态属性获取当前执行线程所在的应用程序域
FriendLyName获取当前应用程序域的友好名称
MonitoringIsEnable获取或设置一个值,该值指示是否对当前进程启用应用程序域的cpu和内存监控,一旦对进程启用了监控,则无法将其禁用
SetupInformation获取给定应用程序域的配置信息,表示为一个AppDomainSetup对象
事件作用
AssemblyLoad在加载程序集到内存时发生
AssemblyResolve在对程序集的解析失败时发生
DomainUnload在即将从主进程中卸载AppDomain时发生
FirstChanceException在应用程序域抛出异常时,该事件将在CLR找到合适的catch语句之前触发
ProcessExit当默认应用程序的父进程退出时,在默认应用程序域上发生
UnhandledException在异常处理程序未捕捉到异常时

应用程序域再次分出上下文边界用于存放对象,见书本P525

 

 

 

http://www.cnblogs.com/leslies2/archive/2012/03/06/2379235.html#c

转载于:https://www.cnblogs.com/Lin-Li/p/6074421.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
.net C#线程超时的解决方案,使用的时候在被调线程入口调用一下这个方法就可以。更多详细代码见附件 Report.RegisterThread(Report.GetCurrentWin32ThreadID(),Thread.CurrentThread); #region 获取当取线程的ThreadID [DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)] public static extern Int32 GetCurrentWin32ThreadID(); #endregion #region 登记访问任务子线程 /// /// 访问任务子线程 /// public static Hashtable TaskThreadIDTable = Hashtable.Synchronized(new Hashtable()); private static int[] TaskThreadIDs { get { int[] IDs = new int[TaskThreadIDTable.Keys.Count]; TaskThreadIDTable.Keys.CopyTo(IDs, 0); return IDs; } } public static void RegisterThread(int _threadid, System.Threading.Thread thread) { if (!TaskThreadIDTable.ContainsKey(_threadid)) TaskThreadIDTable.Add(_threadid, thread); if (!ExitInvalidThreadLoopRunning) { Thread ExitInvalidThreadLoopThread = new Thread(new ThreadStart(ExitInvalidThreadLoop)); ExitInvalidThreadLoopThread.Priority = ThreadPriority.AboveNormal; ExitInvalidThreadLoopThread.Start(); } } #endregion #region 关闭,退出超时的用户线程 private static DateTime ExitInvalidThreadLoop_LastRunTime = DateTime.Now.Subtract(new TimeSpan(1, 0, 0, 0, 0)); private static bool ExitInvalidThreadLoopRunning { get { return DateTime.Now.Subtract(ExitInvalidThreadLoop_LastRunTime).TotalMinutes 10) { try { Thread thread = (Thread)TaskThreadIDTable[t.Id]; thread.Abort(); } catch { } t.Dispose(); } } #endregion } #endregion
.net C#线程超时的解决方案,使用的时候在被调线程入口调用一下这个方法就可以。更多详细代码见附件 Report.RegisterThread(Report.GetCurrentWin32ThreadID(),Thread.CurrentThread); #region 获取当取线程的ThreadID [DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)] public static extern Int32 GetCurrentWin32ThreadID(); #endregion #region 登记访问任务子线程 /// <summary> /// 访问任务子线程 /// </summary> public static Hashtable TaskThreadIDTable = Hashtable.Synchronized(new Hashtable()); private static int[] TaskThreadIDs { get { int[] IDs = new int[TaskThreadIDTable.Keys.Count]; TaskThreadIDTable.Keys.CopyTo(IDs, 0); return IDs; } } public static void RegisterThread(int _threadid, System.Threading.Thread thread) { if (!TaskThreadIDTable.ContainsKey(_threadid)) TaskThreadIDTable.Add(_threadid, thread); if (!ExitInvalidThreadLoopRunning) { Thread ExitInvalidThreadLoopThread = new Thread(new ThreadStart(ExitInvalidThreadLoop)); ExitInvalidThreadLoopThread.Priority = ThreadPriority.AboveNormal; ExitInvalidThreadLoopThread.Start(); } } #endregion #region 关闭,退出超时的用户线程 private static DateTime ExitInvalidThreadLoop_LastRunTime = DateTime.Now.Subtract(new TimeSpan(1, 0, 0, 0, 0)); private static bool ExitInvalidThreadLoopRunning { get { return DateTime.Now.Subtract(ExitInvalidThreadLoop_LastRunTime).TotalMinutes < 10; } } private static void ExitInvalidThreadLoop() { while (true) { ExitInvalidThread(); ExitInvalidThreadLoop_LastRunTime = DateTime.Now; //每10秒检查一次 Thread.Sleep(10 * 1000); } } private static void ExitInvalidThread() { #region 移除不存在的线程(比如线程运行完正常退出终了) Hashtable AllCurrentThreadIDs = new Hashtable(); ProcessThreadCollection ps = Process.GetCurrentProcess().Threads; foreach (ProcessThread t in ps) { AllCurrentThreadIDs.Add(t.Id, null); } int[] IDs = (int[])TaskThreadIDs.Clone(); foreach (int ID in IDs) { if (!AllCurrentThreadIDs.ContainsKey(ID)) TaskThreadIDTable.Remove(ID); } #endregion #region 退出超时的线程 foreach (ProcessThread t in ps) { //跳过非任务线程 if (!TaskThreadIDTable.ContainsKey(t.Id)) continue; //退出超时线程 TimeSpan ts = DateTime.Now.Subtract(t.StartTime); if (ts.TotalMinutes > 10) { try { Thread thread = (Thread)TaskThreadIDTable[t.Id]; thread.Abort(); } catch { } t.Dispose(); } } #endregion } #endregion
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值