一、委托
//声明委托
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;
}
}
}