引言

本文主要是介绍进程(Process)、应用程序域(AppDomain)、.NET上下文(Context)的概念与操作。
虽然在一般的开发当中这三者并不常用,但熟悉三者的关系,深入了解其作用,对提高系统的性能有莫大的帮助。
在本篇最后的一节当中将会介绍到三者与线程之间的关系,希望对多线程开发人员能提供一定的帮助。
因为时间仓促,文中有错误的地方敬请点评。

目录

一、进程的概念与作用

二、应用程序域

三、深入了解.NET上下文

四、进程应用程序域与线程的关系

 

一、进程的概念与作用

进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。进程之间是相对独立的,一个进程无法直接访问另 一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域 的。进程可以理解为一个程序的基本边界。

 

1.1 Process 的属性与方法

在 System.Diagnostics 命名空间当中存在Process类,专门用于管理进程的开始、结束,访问进程中的模块,获取进程中的线程,设定进程的优先级别等。
表1.0 显示了Process类的常用属性:
 

属性 说明
BasePriority 获取关联进程的基本优先级。
ExitCode 获取关联进程终止时指定的值。
ExitTime 获取关联进程退出的时间。
Handle 返回关联进程的本机句柄。
HandleCount 获取由进程打开的句柄数。
HasExited 获取指示关联进程是否已终止的值。
Id 获取关联进程的唯一标识符。
MachineName 获取关联进程正在其上运行的计算机的名称。
MainModule 获取关联进程的主模块。
Modules 获取已由关联进程加载的模块。
PriorityClass 获取或设置关联进程的总体优先级类别。
ProcessName 获取该进程的名称。
StartInfo 获取或设置要传递给Process的Start方法的属性。
StartTime 获取关联进程启动的时间。
SynchronizingObject 获取或设置用于封送由于进程退出事件而发出的事件处理程序调用的对象。
Threads 获取在关联进程中运行的一组线程

 表1.0

除了上述属性,Process类也定义了下列经常使用的方法:
 

方法 说明
GetProcessById 创建新的 Process 组件,并将其与您指定的现有进程资源关联。
GetProcessByName 创建多个新的 Process 组件,并将其与您指定的现有进程资源关联。
GetCurrentProcess 获取新的 Process 组件并将其与当前活动的进程关联。
GetProcesses 获取本地计算机上正在运行的每一个进程列表。
Start 启动一个进程。
Kill 立即停止关联的进程。
Close 释放与此组件关联的所有资源。
WaitForExit 指示 Process 组件无限期地等待关联进程退出。

 表1.1

Process类的详细信息可以参考 http://msdn.microsoft.com/zh-cn/library/system.diagnostics.process.aspx
下面将举例介绍一下Process的使用方式

 

1.2 建立与销毁进程

利用 Start 与Kill 方法可以简单建立或者销毁进程,下面例子就是利用 Start 方法启动记事本的进程,并打开File.txt文件。2秒钟以后,再使用 Kill 方法销毁进程,并关闭记事本。

         static void Main(string[] args)
         {
             Process process = Process.Start("notepad.exe","File.txt");
             Thread.Sleep(2000);
             process.Kill();
         }

 

1.3 列举计算机运行中的进程

在表1.0 中可以看到,使用 GetProcesses 方法可以获取本地计算机上正在运行的每一个进程列表。
而进程的 Id 属性是每个进程的唯一标志,通过下面的方法,可以显示当前计算机运行的所有进程信息。
因为篇幅关系,下面例子只获取前10个进程。

 1         static void Main(string[] args)
 2         {
 3             var processList = Process.GetProcesses()
 4                 .OrderBy(x=>x.Id)
 5                 .Take(10);
 6             foreach (var process in processList)
 7                 Console.WriteLine(string.Format("ProcessId is:{0} \t ProcessName is:{1}",
 8                     process.Id, process.ProcessName));
 9             Console.ReadKey();
10         }

运行结果

 

如果已知进程的Id,就可以通过 GetProcessById 方法获取对应的进程。

         static void Main(string[] args)
         {
             try
             {
                 var process = Process.GetProcessById(1772);
                 Console.WriteLine("Process name is:" + process.ProcessName);
             }
             catch (ArgumentException ex)
             {
                 Console.WriteLine("Process is nothing!");
             }
             Console.ReadKey();
         }


同样地,你也可能通过GetProcessByName方法获取多个对应名称的进程。

注意:如果不能找到当前ID的进程,系统就会抛出ArgumentException异常。所以使用方法 GetProcessById 获取进程时应该包含在 try{...} catch{..} 之内。

 

1.4 获取进程中的多个模块

在表1.0 中包含了Process类的Modules属性,通过此属性可能获取进程中的多个模块。
这些模块可以是以 *.dll 结尾的程序集,也可以是 *.exe 结尾的可执行程序。
下面的例子就是通过 Process 的 GetCurrentProcess 方法获取当前运行的进程信息,然后显示当前进程的多个模块信息。

1         static void Main(string[] args)
2         {
3             var moduleList = Process.GetCurrentProcess().Modules;
4             foreach (System.Diagnostics.ProcessModule module in moduleList)
5                 Console.WriteLine(string.Format("{0}\n  URL:{1}\n  Version:{2}",
6                     module.ModuleName,module.FileName,module.FileVersionInfo.FileVersion));
7             Console.ReadKey();
8         }

运行结果: