进程:一个程序就是一个进程,但是也有一个程序需要多个进程来支持的情况
进程要使用的类是:Process
它在命名空间:System.Diagnostics;
静态方法Start();
Process.Start("进程名称");
也可以实例化对象,来调用Start()普通方法,但调用普通方法之前需要给
StartInfo属性设置一个对象,来通知它要打开的是哪个进程
Process p = new Process(); ProcessStartInfo psi = new ProcessStartInfo("完整exe文件路径名"); p.StartInfo = psi; p.Start();
线程:
一个进程就像是一个公司,默认只有一个老板
老板叫做 主线程
主线程一旦让它去执行一段需要时间的代码,那么就会出现程序假死,失去控制
原因是:线程同一时间只能做一件事,而主线程是操作窗体控制的,一旦被占用,那么窗体就没人控制了。
解决办法:
招一个员工帮老板干这个活
开启线程:
线程基本使用:
//创建一个线程对象,告诉它要执行的是哪一个方法 Thread th = new Thread(aaa); //准备好了,开始执行,不是立即开始,CPU决定什么时候开始 th.Start();
需要跨线程访问对象:
程序默认不允许跨线程访问对象,因为监控开着
需要关闭监控
在构造函数的构造方法下面写上:
Control.CheckForIllegalCrossThreadCalls = false;
需要传参的线程:
线程需要执行一个方法,而这个方法允许有一个参数,并且这个参数必须是object类型的
Start的时候可以传一个object
th.Start(sender);
程序退出立刻关闭所有线程:
线程默认开启为前台线程,程序必须将所有的前台线程执行完毕后才会真正退出程序
解决办法:将线程变为后台线程
th.IsBackground = true;
TreeView递归加载树形菜单
最好不要直接访问数据库进行加载,
方法有二:
一:查询全部数据存入List<>进行修改
二:查询全部数据存入DataSet进行修改
List<China> AllList = new List<China>(); public Form1() { InitializeComponent(); AllList = new ChinaData().Select(); TreeNode tn1 = new TreeNode("中国"); tn1.Tag = "; NodesBind(tn1); treeView1.Nodes.Add(tn1); } public void NodesBind(TreeNode tn) { //lambda 表达式 List<China> clist = AllList.Where(r => r.ParentAreaCode == tn.Tag.ToString()).ToList(); foreach (China c in clist) { TreeNode tnn = new TreeNode(c.AreaName); tnn.Tag = c.AreaCode; NodesBind(tnn); tn.Nodes.Add(tnn); } }
方法一
发送邮件:
//设置要调用的发送邮件的服务器 SmtpClient smtp = new SmtpClient("smtp.sina.cn"); //创建发信人对象 MailAddress from = new MailAddress(textBox1.Text); //创建收信人对象 MailAddress to = new MailAddress(textBox2.Text); //要发送的邮件对象,包含4个内容需要填充 MailMessage mail = new MailMessage(from, to); //设置邮件的标题 mail.Subject = textBox3.Text; //设置邮件的主体正文内容 mail.Body = textBox4.Text; //创建发件人身份验证凭证 NetworkCredential cred = new NetworkCredential(textBox1.Text, textBox5.Text); //将凭证证书绑定到服务端对象上,一并发送出去 smtp.Credentials = cred; //此服务器对象执行发送邮件功能 smtp.Send(mail);
简单的邮件发送DLL:Email.zip