zoukankan      html  css  js  c++  java
  • 1.2. .net和C#对线程的支持(学习)

    本节需要了解:

    •   什么是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(线程本地存储器),确定是否存在托管的对象。如果找到了一个托管线程对象,运行库就使用那个线程。如果没有的就创建一个并使用。这个过程很简单,但是必要的。因为运行库不为这类内部调用和创建线程,就不能在托管的环境中标识线程,更不能控制它了。

        

        

  • 相关阅读:
    深入理解计算机系统
    Python基础知识点
    贝叶斯分类器
    matplotlib 库的使用
    Linux 学习笔记
    支持向量机
    神经网络
    决策树
    k近邻法的实现
    智能过滤:九眼过滤管应对千变万化
  • 原文地址:https://www.cnblogs.com/jzhou/p/3504066.html
Copyright © 2011-2022 走看看