zoukankan      html  css  js  c++  java
  • 滴水穿石 C#中多线程 委托的使用

    什么是多线程?我们在建立以个C#项目时,往往会在Form1上添加控件,然后写代码,初
    学者都是在重复这个过程,其实这个过程是单线程的,可以理解为只有“main”主线程,有
    的时候往往需要同时测量多个东西,比如说在扫面局域网主机时,如果按一个一个主机的IP
    去扫描,会很浪费时间,因为当一个主机未开机,会对这个主机等待一直到超时。如果建立
    多个线程,让所有的IP 扫描分配给不同的线程去执行,因此会节省很多时间,尤其是扫面
    的IP段主机大部分没开机,和单线程比花费的时间差很多。 
     
     
    因为我也是初学者,谈的很肤浅,关于进程、线程的概念还是去看高手的理解吧。不过有一
    点,多线程未必会比单线程节省时间,上面的例子是节省时间的例子之一,但并不是说所有
    多线程的程序比单线程程序节省时间。这要分情况看。 
     
    下面说一下怎么使用多线程。(将在后面附有例子) 
    第一步:在主程序前加上using system.threading 
    第二部:线程实例化,一般是在主程序最前端声明thread    thread1; 
    第三部:在调用线程的方法中给线程分配内存,准备启动线程  thread1=  new  thread(方法
    名)方法名指的是线程的入口,即要执行的方法。然后启动线程:thread1.start(); 
    第四步:终止线程 
    终止线程有两种方法,一种是使用建立公共布尔类型,在线程内部时刻检查布尔值,通过在
    外界改变布尔类型的值,来控制线程的结束。 
    第二种是强制退出线程,即调用thread1..abort();与此方法连用的是thread1.join();为什么要
    连用呢?因为虽然线程强制退出,但是并不知道线程终止的具体时间,所以把强制退出的线
    程合并到主线程中来。值得注意的是线程强制退出后不能够用thread1.Resume()重启线程。
    所以强制线程退出的方法慎用。 
     
    什么是委托呢?举一个最实用的例子,刚才是不是已经知道建立多线程了,但是自己建立的
    线程时不能访问其他线程的东西,比如说自己建立的线程是不能访问窗体上的任何控件,但
    是自己建立的线程很想用到窗体中的控件怎么呢?那就用委托吧。委托时系统专门用作协调
    线程之间的关系的。 
    委托的定义 
    Delegate  (返回值类型)delegatename(委托名称)(参数列表) 
    例子:delegate void list(); 
        Delegate string name(string s); 
    委托实例化 
    list list1; 
    list1=new list(方法名); 
     
    调用委托 
    此时委托list1 将作为调用委托的方法的一个参数。如listBox1.Invoke(list1); 

    下面是一个涉及线程和委托综合的小例子。 

    using System;  
    using System.ComponentModel;  
    using System.Drawing;  
    using System.Text;  
    using System.Windows.Forms;  
    using System.Threading;//使用多线程的声明(准确的说是要在main主线程中建立新的线程时要进行的引 
        public partial class Form1 : Form  
            public static int Num = 0;  
            Thread thread1; //在主线程中声明线程1  
            Thread thread2; //在主线程中声明线程2  
            daililist list1;//委托实例化,即建立委托对应的事件  
                InitializeComponent();  
                list1 = new daililist(updatelist);//委托处理的方法,这里updatelist是一个方法,这个句子的意思是把updatelist这个方法交给了list1这个委托实例  
                thread1 = new Thread(numadd );  

                thread1.Start();  
                thread2.Start();  
            public void updatelist()  
                listBox1.Items.Add (Num) ;  
            public void numadd()  
                Num ++;  
    listBox1.Invoke(list1);//这是自己建立的线程要调用的方法,但是listbox1是main主线程建立的控件,自定义的线程无法直接访问,上面已经定义了委托,此处应用listbox1的invoke  
    //到此我们理一下思路,建立线程thread1、thread2,这两个线程都指向了numadd这个方法,首先都执行Num++,然后执行listBox1.Invoke(list1),意思是说将要对listbox1操作,  
            private void button2_Click(object sender, EventArgs e)  
                thread1.Join();  
                thread2.Abort();  
            }  
        }  


     

    using System.Collections.Generic; 
    using System.Data; 
    using System.Linq; 
    用说明) 
     
    namespace mytest 
    { 
         
        { 
            delegate void daililist();//主线程之外的线程要调用main线程中建立的控件,需要使用委托的方式,此处是委托的定义 
            public Form1() 
            { 
            } 
     
            private void button1_Click(object sender, EventArgs e) 
            { 
                thread2 = new Thread(numadd); 
     
            } 
            { 
            } 
            { 
    //方法把所有对listbox1的操作都交给委托list1去处理。 
    //但是具体操作在list1这个委托当中,然后这个委托指向了updatelist并执行,至此thread1、thread2都完成了对listbox1的操作! 
            } 
     
            { 
                thread1.Abort(); 
                thread2.Join(); 
  • 相关阅读:
    c++ 从vector扩容看noexcept应用场景
    c++11-17 模板核心知识(十一)—— 编写泛型库需要的基本技术
    动态链接的PLT与GOT
    c++11-17 模板核心知识(十)—— 区分万能引用(universal references)和右值引用
    Golang性能分析与优化
    c++11-17 模板核心知识(九)—— 理解decltype与decltype(auto)
    [LuoguP4808][CCC 2018]平衡树(数论分块+记忆化搜索)(有复杂度证明)
    [NOI2016]区间(线段树+尺取法)
    [BZOJ4316]小C的独立集(仙人掌+树形DP)
    [CTSC2002]灭鼠行动(模拟)
  • 原文地址:https://www.cnblogs.com/asdyzh/p/9876623.html
Copyright © 2011-2022 走看看