当前位置: 首页 > news >正文

WebCast听课录(5)

课程名:Windows应用程序开发入门到精通六:如何使用.NET开发Windows应用程序
 
程序的托管执行
程序集
名称空间
委托
线程
应用程序域
特性
数据类型
反射
 
1,托管代码指第一次编译形成中间代码(MSIL),执行时需要再编译成本地代码(二进制代码).类加载器会加载中间语言代码,或dll中的类库,再调用JIT来编译为托管的本地代码,最后被托管地执行,在执行时会不断地进行安全性策略检查。在加载dll类库时,不是全部装载,而只是装载Main()方法所在的class,在执行时会检查所要调用的类是否已经在内存中,若没有则实时装载进来。



2006101705.jpg 

   2,IDisposable 接口 定义一种释放分配的非托管资源的方法。当托管对象不再使用时,垃圾回收器会自动释放分配给该对象的内存,不过,进行垃圾回收的时间不可预知。另外,垃圾回收器对窗口句柄、打开的文件和流等非托管资源一无所知。将此接口的 Dispose 方法与垃圾回收器一起使用来显式释放非托管资源。当不再需要对象时,对象的使用者可以调用此方法。

using System;
using System.ComponentModel;

// The following example demonstrates how to create
// a resource class that implements the IDisposable interface
// and the IDisposable.Dispose method.

public class DisposeExample
{

    //实现IDisposable的基类,通过实现此接口,就表明此类型的实例会分配非托管资源
    public class MyResource: IDisposable
    {
        
        private IntPtr handle;//指向一个内部非托管资源的指针
        
        private Component component = new Component();//类中使用的其他托管资源
    
        private bool disposed = false;//跟踪Dispose是否已经被调用

    
        public MyResource(IntPtr handle)
        {
            this.handle = handle;
        }


        //实现IDisposable接口,不要让此方法virtual。派生类应该不允许override这个方法
        public void Dispose()
        {
            Dispose(true);
            //此对象将被Dispose方法清理掉,因此,你需要调用GC.SuppressFinalize方法来
            //将此对象从需要终止的对象队列中移除,并且防止这个对象执行两次终止代码
            GC.SuppressFinalize(this);
        }


        //若disposing为true,则方法被用户代码直接或间接调用。托管资源和非
        //托管资源可以被释放。
        //若disposing为false,则方法被运行时从解析器内部调用并且你不应该再应用其他对象,
        //只有非托管资源能被释放。
        private void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if(!this.disposed)
            {//检查Dispose是否已经被调用过了
            
                if(disposing)
                {//若disposing为true,释放所有托管和非托管资源

                    component.Dispose();    // 在此处释放托管资源

                }
             
                // 在这调用适当的方法来清理非托管资源,
                // 若disposing为false,则只有下面的代码会执行 
                CloseHandle(handle);
                handle = IntPtr.Zero;            
            }
            disposed = true;         
        }

        // Use interop to call the method necessary  
        // to clean up the unmanaged resource.
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);

        //这个解析器只在Dispose方法没有被调用时才运行,它为你的基类提供了解析的
        //机会。在其派生类中不要提供解析器。
        ~MyResource()      
        {
            Dispose(false);//解析器内部调用,只释放非托管资源,托管资源由垃圾回收器负责
        }
    }
    public static void Main()
    {
        // Insert code here to create
        // and use the MyResource object.   
    }
}



3,COM Marshaller用于与COM进行互操作,CLR会把 COM组件包装成一个应用程序集,在此应用程序集中会把方法中使用的参数类型都映射为CLR的数据类型,CLR就会和COM Marshaller进行交互,而后者与真正的COM组件进行交互。
   
4,.NET Framework 允许您异步调用任何方法。定义与您需要调用的方法具有相同签名的委托;公共语言运行库将自动为该委托定义具有适当签名的 BeginInvoke 和 EndInvoke 方法。

   BeginInvoke 方法用于启动异步调用。它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数。BeginInvoke 立即返回,不等待异步调用完成。BeginInvoke 返回 IasyncResult,可用于监视调用进度。EndInvoke 方法用于检索异步调用结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;如果异步调用未完成,EndInvoke 将一直阻塞到异步调用完成。EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数以及由 BeginInvoke 返回的 IAsyncResult。
 
调用了 BeginInvoke 后,可以:
1,进行某些操作,然后调用 EndInvoke 一直阻塞到调用完成。
2,使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,使用它的 WaitOne 方法将执行一直阻塞到发出WaitHandle 信号,然后调用 EndInvoke。
3,轮询由 BeginInvoke 返回的 IAsyncResult,确定异步调用何时完成,然后调用 EndInvoke。
4,将用于回调方法的委托传递给 BeginInvoke。该方法在异步调用完成后在 ThreadPool 线程上执行,它可以调用 EndInvoke。 

    public delegate bool SimpleDelegate(string Message);

    public class DelegateExample
    {
        public DelegateExample()
        {
        }

        public void CallMeBack(SimpleDelegate CallBack)
        {
            IAsyncResult result = CallBack.BeginInvoke("Calling you back from thread"+System.AppDomain.GetCurrentThreadId(),null,null);

            bool callBackResult = (bool)CallBack.EndInvoke(result);
            System.Windows.Forms.MessageBox.Show(callBackResult.ToString(),"Callback Result");

        }
    }

    public class Test
    {
        public static void Main()
        {
            Delegates();
        }
    
        public static bool SimpleDelegateHandler(string Message)
        {
            System.Windows.Forms.MessageBox.Show(Message,
                "Code Running On Thread ID"+System.AppDomain.GetCurrentThreadId().ToString());
            return true;
        }
        public static void Delegates()
        {
            DelegateExample ex = new DelegateExample();
            ex.CallMeBack(new SimpleDelegate(SimpleDelegateHandler));

        }

    }


5,线程应用示例:

        public delegate void DoneDelegate(bool arg);

        private void DelegateHandler(bool Stopped)
        {
            btnStart.Text = "Save";

            if(Stopped)
            {
                MessageBox.Show("Save Stopped","Stopped",
                    MessageBoxButtons.OK,MessageBoxIcon.Warning);
            }
            else
            {
                MessageBox.Show("Save Done");
            }
        }

        private void ProcessSave()
        {
            bool Stopped = false;
            for(int i=1;i<=50;i++)
            {
                System.Threading.Thread.Sleep(100);
                if(btnStart.Text == "Stopped")
                {//用户要求停止
                    Stopped = true;
                    break;
                }
            }
            new DoneDelegate(DelegateHandler).BeginInvoke(Stopped,null,null);//开始异步回调
        }


        private void btnStart_Click(object sender, System.EventArgs e)
        {
            if(btnStart.Text=="start")
            {
                btnStart.Text = "Stop";
                System.Threading.Thread t = new Thread(new System.Threading.ThreadStart
                    (ProcessSave));
                t.Start();//启动新线程来处理
            }
            else
            {
                btnStart.Text = "Stopped";
            }
        }


通过delegate可以把界面元素和处理代码隔离开,并且后者可以去访问界面元素(尽管两者不是同一个类下的成员)

6,思考题:
[assembly:CLSCompliant(true)]
//[CLSCompliant(false)] 
    public class Class2
    {

        public static void Main(String[] args)
        {
            UInt32 a1 = GetMinValue();
            UInt32 a2 = GETMINVALUE();
        }

        public static UInt32 GetMinValue()
        {
            return UInt32.MinValue;

        }

        public static UInt32 GETMINVALUE()
        {
            return UInt32.MinValue;

        }
    }


如果编译上面这段代码,会有什么问题?会报两种错误,因为[assembly:CLSCompliant(true)]指定了要遵从CLS性,因此由于 CLS 中没有指定 UInt32 类型,所以返回类型会报错,而且两个方法的签名除了大小写以外是一样的,因此也不符合CLS,(例如在VB.net里就区分不出大小写的差别,尽管在C#是可以区分的。)
 
当然,若把去掉[CLSCompliant(false)]的注释,就指明了此类是不需要符合CLS的,因此就不会报错了。




本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2006/10/17/531930.html,如需转载请自行联系原作者

相关文章:

  • 数字音乐维权联盟首次出招 QQ音乐起诉酷我索赔千万
  • Pure-ftpd无法连接到服务器 425错误
  • 华为交换机ntp设置
  • 同源策略
  • 硬盘驱动器
  • Powershell 修改AD用户属性
  • Unicode和多字节的相互转换
  • 基于C++任意点数的FFT/IFFT(时域和频域)实现
  • 第 19 章 Class
  • 双击防止网页放大缩小HTML5
  • 多种方式求阶乘
  • 开发android App干坏事(二)-wifi控制
  • Net Core中数据库事务隔离详解——以Dapper和Mysql为例
  • FFmpeg常用基本命令
  • java异常——RuntimeException和User Define Exception
  • JavaScript-如何实现克隆(clone)函数
  • 07.Android之多媒体问题
  • JAVA 学习IO流
  • java正则表式的使用
  • Js基础知识(四) - js运行原理与机制
  • Laravel Telescope:优雅的应用调试工具
  • MySQL的数据类型
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • sublime配置文件
  • web标准化(下)
  • 服务器之间,相同帐号,实现免密钥登录
  • 关于Flux,Vuex,Redux的思考
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 使用docker-compose进行多节点部署
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 延迟脚本的方式
  • 湖北分布式智能数据采集方法有哪些?
  • ​flutter 代码混淆
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (C语言)字符分类函数
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (补)B+树一些思想
  • (论文阅读11/100)Fast R-CNN
  • (三分钟)速览传统边缘检测算子
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (十)T检验-第一部分
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (转)程序员疫苗:代码注入
  • (转)负载均衡,回话保持,cookie
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?
  • ::before和::after 常见的用法