黑馬程序員_學習日記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;
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章