黑马程序员_学习日记65_713ASP.NET(委托、托管、扩展方法、泛型委托、进程_应用程序域_线程、多线程、异步委托)

一、委托
 

//声明委托
internal delegate int MyAddFunDel(int a,int b);

class Program
{
    static void Main(string[] args)
    {
        MyAddFunDel funDel = new MyAddFunDel(AddStatic);

        //多播
        funDel += Add2;
        Console.WriteLine(funDel(3,2));
        Console.ReadKey();
    }

    static int AddStatic(int a, int b)
    {
        Console.WriteLine("AddStatic执行了\r\n");
        return a + b;
    }

    static int Add2(int a, int b)
    {
        Console.WriteLine("Add2执行了\r\n");
        return a++;
    }
}


输出结果:
 

#region 匿名函数
MyAddFunDel delFun = delegate(int i, int i1) { return i + i1; };
Console.WriteLine(delFun(3,2));

//lambda  其中 => goto,是lambda的一个标准
MyAddFunDel delLambda = (int i, int i1) => { return i + i1; };

lambda表达式的方法参数类型可以省略,类型由委托定义确定,即
MyAddFunDel delLambda = ( i, i1) => { return i + i1; };
只有一行代码的时候还可以省略花括号,即
MyAddFunDel delLambda = ( i, i1) => return i + i1;

二、托管、非托管
 

三、扩展方法:三要素(静态类、静态方法、this)
FindAll方法的源代码:

public List<T> FindAll(Predicate<T> match)
{
    if (match == null)
    {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
    }
    List<T> list = new List<T>();
    for (int i = 0; i < this._size; i++)
    {
        if (match(this._items[i]))
        {
            list.Add(this._items[i]);
        }
    }
    return list;
}


模拟FindAll的扩展方法(MyFindStrs<T>)
namespace可以改为System.Collection.Generic,将扩展方法的命名空间和要扩展的类写成一样的
this后面紧跟的类型是扩展方法要加到的类型
方法名后面紧跟的泛型约束是最主要的
list.MyFindStrs<String>  其中<String>可以省略

namespace System.Collections.Generic //改namespace,使扩展方法的命名空间和要扩展的类所在命名空间一样
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> list = new List<string>()
            {
                "1",
                "2",
                "3",
                "4"
            };
            //MyFindStrs后面的<string>可以省略,因为调用它的list集合的类型已经确定了(在这里是string)
     //自己模拟的方法
            //var temp = list.MyFindStrs<string>(MyCal);
     
     //普通写法
     //var temp = list.FindAll(MyCal);

     //委托简写(lambda表达式)
     var temp = list.FindAll(a => int.Parse(a) > 2);
            
            foreach (var item in temp)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
     //作为委托参数的方法
        //static bool MyCal(string str)
        //{
        //    if (int.Parse(str) > 2)
        //    {
        //        return true;
        //    }
        //    return false;
        //}
}

//1、声明扩展方法中需要调用的委托类型
public delegate bool IsokDel<T>(T obj);

    public static class MyListExt
    {
        /// <summary>
        /// 扩展方法:静态类、静态方法、this
        /// </summary>
        /// <typeparam name="T">方法名后面紧跟的泛型约束是最主要的</typeparam>
        /// <param name="list">this后面紧跟的类型是扩展方法要加到的类型</param>
        /// <param name="del"></param>
        /// <returns></returns>
        public static List<T> MyFindStrs<T>(this List<T> list, IsokDel<T> del)
        {
//2、根据扩展方法返回的数据类型声明变量            
List<T> result = new List<T>();
//3、遍历使用扩展方法的类的对象
            foreach (var item in list)
            {
//4、调用委托参数传递的方法来处理每个对象
                if (del(item))
                {
                    result.Add(item);
                }
            } 
//5、返回处理后的对象
            return result;
        }
    }
}


四、泛型委托(Func和Action)
(一)Func
 
把一个委托传到一个方法里,然后在方法中调用
Func一共有16个重载,最后一个参数是返回值
(二)Action<int,int> 没有返回值

五、进程、应用程序域、线程
应用程序域、进程、线程之间的关系:
一个进程可以有多个应用程序域,一个应用程序域可以执行多个线程,但同一时间线程只能在一个应用程序域中执行。
 
(一)进程
每个进程都有一个独立的内存空间,进程是在应用程序级别的隔离。

//启动IE,把传智首页打开
//Process process = Process.Start("iexplore.exe", "http://www.itcast.cn");

//获得所有进程
var processes = Process.GetProcesses();
foreach (var item in processes)
{
    Console.WriteLine(item.ProcessName);
}
//kill当前进程
Process p = Process.GetCurrentProcess();
Thread.Sleep(1000);
p.Kill();


(二)应用程序域

//AppDomain.Unload(AppDomain.CurrentDomain);//卸载当前AppDomain,由于是主域,不能卸载
if(AppDomain.CurrentDomain.IsDefaultAppDomain())//判断是否为主应用程序域
{
 Console.WriteLine("这是主域");
}

//自己写一个AppDomain
AppDomainSetup appDomainSetup = new AppDomainSetup();
appDomainSetup.LoaderOptimization = LoaderOptimization.SingleDomain;

AppDomain appDomain = AppDomain.CreateDomain("MultThread", null, appDomainSetup);
appDomain.ExecuteAssembly("MultThread.exe");


引用第三方的exe

(三)线程:
线程是操作系统执行的最小单位
线程切换19~30毫秒
1、

static void Main(string[] args)
{
    #region 创建线程
    //获取当前线程
    Thread mainThread = Thread.CurrentThread;
    Console.WriteLine("主线程的id是:{0}", mainThread.ManagedThreadId);

    //创建线程
    //ThreadStart 表示在 System.Threading.Thread 上执行的方法,在此即DoWork
    Thread thread = new Thread(DoWork);
    thread.Name = "shit";//设置线程名
    thread.IsBackground = true;
    //启动一个线程(不是真正的启动,告诉CPU当前线程可以执行了)
    thread.Start();
    #endregion
    Console.ReadKey();
}

static void DoWork()
{
    Console.WriteLine("这是子线程在干活呢...,它的Id是{0}",Thread.CurrentThread.ManagedThreadId);
}


线程分为:CLR线程、操作系统线程。目前CLR线程和操作系统线程做了一一对应。
thread.Abort(); //终止线程
thread.Priority = ThreadPriority.Normal; //线程级别:微软对windows线程分0-31级
前台线程:线程执行完毕程序才关闭。
后台线程:主线程关闭,后台自动关闭。
 
2、带参数的线程:

Thread thread = new Thread(a =>
{
    while (true)
    {
        Console.WriteLine("这是子线程在干活呢...参数值:{0},线程Id是{1}",a,Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(1000);
    }
});
thread.IsBackground = true;
thread.Start(2);
Console.ReadKey();


传递多个参数可以用List
3、内部实现:

public class MyThread
{
    public ParameterizedThreadStart callBackFunc { get; set; }
    //这里的start是委托调用的方法
    public MyThread(ParameterizedThreadStart start)
    {
        callBackFunc = start;
    }
    //这里的Start是thread.Start();
    public void Start(object obj)
    {
        callBackFunc(obj);
    }
}


六、多线程

namespace 多线程窗体间传值
{
    public delegate void TxtDel(string txt);

    public partial class MainFrm : Form
    {
        private TxtDel SetTextDel;

        public MainFrm()
        {
            InitializeComponent();
            //允许其他线程来访问当前线程创建的控件
            //掩耳盗铃法
            //Control.CheckForIllegalCrossThreadCalls = false;
            this.SetTextDel = SetText4OtherThread;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //TxtFrm txtFrm = new TxtFrm();
            //txtFrm.TxtFrmDel = SaveTxt;//将SaveTxt方法传给txtFrm的委托变量
            //txtFrm.Show();

            Thread thread = new Thread(() =>
            {
                TxtFrm txtFrm = new TxtFrm();
                txtFrm.TxtFrmDel = SaveTxt;//将SaveTxt方法传给txtFrm的委托变量
                txtFrm.ShowDialog();//非模态
            });
            thread.Start();
        }

        void SaveTxt(string txt)
        {
            //InvokeRequired 当线程执行到此时,校验textBox1控件是哪个线程创建的,如果是自己创建的InvokeRequired为false,反之为true
            if (this.textBox1.InvokeRequired)
            {
                this.Invoke(this.SetTextDel,txt);//加上txt
            }
            else
            {
                this.textBox1.Text = txt;
            }
        }

        public void SetText4OtherThread(string strTxt)
        {
            this.textBox1.Text = strTxt;
        }
    }
}


七、异步委托
 

namespace 异步委托
{
    internal delegate int MyAddFunDel(int a,int b);

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("主线程Id:{0}",Thread.CurrentThread.ManagedThreadId);
            MyAddFunDel myDel = new MyAddFunDel(AddStatic);
            
            //myDel(1,3);
            IAsyncResult delResult = myDel.BeginInvoke(3, 4, null, 2);
            while (!delResult.IsCompleted)
            {
                //主线程干其他事
            }
            int addResult = myDel.EndInvoke(delResult);
            Console.WriteLine("主线程获得结果是:{0}",addResult);

            Console.ReadKey();
        }

        static int AddStatic(int a, int b)
        {
            Console.WriteLine("AddStatic执行了..."+Thread.CurrentThread.ManagedThreadId+"\r\n");
            Thread.Sleep(3000);
            return a + b;
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值