您的位置:首页 > 编程语言 > C#

1.2. .net和C#对线程的支持(学习)

2014-01-03 17:32 225 查看
本节需要了解:

  什么是System.AppDomain类,可以使用该类做什么

  .Net运行库是如何监控线程的

  1. System.AppDomain 类

    之前了解,进程是内存和资源的一个物理独立的部分,后来又提到一个进程至少有一个线程。

    当Microsoft设计.Net Framewrok时,新增了一个隔离层,称为应用程序域或AppDomain。应用程序不是进程那样是一个物理独立的部分,而是进程内部的一个逻辑独立部分。在一个进程中可以存在多个应用程序域。通常,标准的进程不使用代理,就不可以访问其它进程的数据(之前说明了,进程都是独立的操作数据的).使用代理会耗费很多系统资源,编码也会变得很复杂。但是引入应用程序的概念,就可以在同一个进程中启动好几个应用程序域,进程所提供的同一个隔离区域可以和应用程序一起使用。线程可以跨多个应用程序域来执行,且不需要耗费因线程内部通信而产生的系统开销。

    Microsoft把这些应用程序域的所有功能都封装在一个名为System.AppDomain的类中。为了了解一下System.AppDomain

    1.1.设置AppDomain数据

      创建一个控制台MyAppDomain:

      

namespace MyAppDomain
{
public class Program
{
public AppDomain Domain;
public int ThreadId;
public void SetDomainDate(string vName, string vValue)
{
Domain.SetData(vName, (object)vValue);
ThreadId = AppDomain.GetCurrentThreadId();
}

public T GetDomainData<T>(string vName)
{
return (T)Domain.GetData(vName);
}
static void Main(string[] args)
{
var DataName = "MyData";
var DataValue = "Some Data";
Console.WriteLine("开始");
Program obj = new Program();
obj.Domain = AppDomain.CurrentDomain;
obj.SetDomainDate(DataName, DataValue);
Console.WriteLine("输出System.AppDomain数据");
Console.WriteLine(string.Format("数据存储的key:{0},取出的值为:{1},获取当前线程id:{2}",DataName,obj.GetDomainData<string>(DataName),obj.ThreadId));
Console.Read();

}
}
}


执行之后会输出:
    开始

    输出System.AppDomain数据

    数据存储的key:MyData,取出的值为:Some Data,获取当前线程id:22388(ThreadId是根据当前系统环境自动分配而获取)

1.2.在指定的应用程序域中执行代码

    创建新的应用程序域,着重介绍在新建的AppDomain中创建新线程时的有关行为,源代码:

    

namespace CreateAppDomians
{
class Program
{
static void Main(string[] args)
{
AppDomain DomainA;
DomainA = AppDomain.CreateDomain("MyDomainA");//创建一个应用程序域,域名为:MyDomainKeyA
string stringA = "值1";
DomainA.SetData("DomainKey", stringA);

CommonCallBack();//直接调用这方法会创建一个新应用程序域,这时候就有两个应用程序了

CrossAppDomainDelegate delegateA = new CrossAppDomainDelegate(CommonCallBack);//这里使用跨应用程序域的调用的
DomainA.DoCallBack(delegateA);//委托把另一程序域委托给由指定的应用程序执行

Console.Read();
}

public static void CommonCallBack() {
AppDomain Domain;
Domain = AppDomain.CurrentDomain;
Console.WriteLine("获取当前线程保存的值value:'{0}',获取可执行程序的名称:{1},ThreadId:{2}", Domain.GetData("DomainKey"), Domain.FriendlyName.ToString(), AppDomain.GetCurrentThreadId());
}
}
}


输出的结果为:

    获取当前线程保存的值value:'',获取可执行程序的名称:CreateAppDomians.exe,ThreadId:13007

    获取当前线程保存的值value:'值1',获取可执行程序的名称:MyDomainA,ThreadId:13007

从再次调用GetCurrentThreadId()方法。在程序输出结果中,无论当中的应用程序执行,得到的线程的ID都是一样的。这一点很重要,因为这不仅意味着AppDomain可以有零个或多个线程,而且能够跨不同的域来执行线程。

2.线程管理与.net运行库

  .Net Framework不仅提供了对自由线程的进程和逻辑应用程序的支持,还提供了处理线程的对象,这些对象表示都是System.Threading.Thread类的实例。而在了解System.Threading.Thread之前先要了解托管线程和非托管线程的关系。 说得笼统点,非托管线程(在.net外部创建)是如何与托管线程类的实例(表示运行在.net CRL内部的线程)发生关联。

    当非托管线程在托管线程中执行时,运行库会检查TLS(线程本地存储器),确定是否存在托管的对象。如果找到了一个托管线程对象,运行库就使用那个线程。如果没有的就创建一个并使用。这个过程很简单,但是必要的。因为运行库不为这类内部调用和创建线程,就不能在托管的环境中标识线程,更不能控制它了。

    

    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: