• .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法


    .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法

    1.多线程简单使用
    (1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程
    (2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线程
    (3)线程什么时候结束?如果线程是前台线程,该线程执行的方法执行完以后线程就会自动退出
    (4)后台线程只要所有的前台线程结束,后台线程就会立即结束
    (5)多个线程访问同一资源,可能造成不同步的情况,这个叫做线程重入,可以使用lock加锁将执行的共同方法中的代码加上lock
    (6)thread.Abort();//强行停止线程
    Thread.Sleep(5000);//将当前线程暂停5秒
    Thread th = Thread.CurrentThread;//获得当前运行代码的线程
    th.Name="线程名字"
    (7)简单使用
    //创建一个线程对象,并为这个线程对象指定要执行的方法
    Thread thread = new Thread(Test);
    //设置线程为后台线程
    thread.IsBackground = true;
    //开启线程
    thread.Start();
    private void Test()
    {
    Console.Write("多线程测试方法");
    }
    线程调用带参数的方法
    static void ParameterizedThread(object obj)
    {
    Console.WriteLine(obj.ToString());
    }
    ParameterizedThreadStart pts = new ParameterizedThreadStart(ParameterizedThread);
    Thread t = new Thread(pts);
    t.IsBackground = true;
    t.Start("我是带参数的线程");
    (8)lock的本质就是调用以下代码
    private static readonly object obj = new object(); 
    bool isGetLocker = false;
    try

    Monitor.Enter(obj,ref isGetLocker);//获取指定对象上的排它锁,可获取一个值,指示是否获取了该锁
    //尝试获取锁,如果获取成功,isGetLocker=true
    }
    catch(Exception ex)
    {
    throw ex;
    }
    finally
    {
    if(isGetLocker)
    {
    Monitor.Exit(obj);//释放对象上的排它锁
    }
    }
    2.线程死锁
    static object locker1 = new object();
    static object locker2 = new object();

    public static void MainThread()
    {
    new Thread(() =>
    {
    lock (locker1) //获取锁locker1
    {
    Thread.Sleep(1000);
    lock (locker2) //尝试获取locker2
    {
    Console.WriteLine("locker1,locker2");
    }
    }
    }).Start();
    new Thread(() =>
    {
    lock (locker2) //获取锁locker2
    {
    Thread.Sleep(1000);
    lock (locker1) //尝试获取locker1
    {
    Console.WriteLine("locker2,locker1");
    }
    }
    }).Start();
    }

    3.线程通信 生产者消费者模式
    所谓生产者消费者模式就是生产一个对象,然后在消费一个对象,线程通信主要是通过Monitor这个类来进行通信的
    public class Dog
    {
    public static object objLock = new object();
    public string name;
    public string gender;
    }

    public class Factory
    {

    private Dog myDog;
    public Factory(Dog d)
    {
    myDog = d;
    }
    public void Change()
    {
    int i = 0;
    while (true)
    {
    lock (Dog.objLock)
    {
    if (i == 0)
    {
    myDog.name = "ruiky";
    myDog.gender = "Male";
    }
    else
    {
    myDog.name = "瑞奇";
    myDog.gender = "Female";
    }
    i = (i + 1) % 2;
    Monitor.Pulse(Dog.objLock);//通知等待队列中的线程锁定对象状态的更改,激活等待队列中
    //和锁相关的线程
    Monitor.Wait(Dog.objLock);//释放对象上的锁并阻止当前线程,直到它重新获取该锁
    }
    }
    }
    }

    public class Customer
    {
    private Dog myDog;
    public Customer(Dog d)
    {
    myDog = d;
    }
    public void Buy()
    {
    while (true)
    {
    lock (Dog.objLock)
    {
    Console.WriteLine(myDog.name + " , " + myDog.gender);
    Monitor.Pulse(Dog.objLock);
    Monitor.Wait(Dog.objLock);
    }
    }
    }
    }
    //------------------------------
    public static void Main(string[] ar)
    {
    Dog d = new Dog();
    Factory f = new Factory(d);
    Thread thrF = new Thread(f.Change);
    thrF.IsBackground = true;
    Customer c = new Customer(d);
    Thread thrC = new Thread(c.Buy);
    thrC.IsBackground = true;

    thrF.Start();
    thrC.Start();
    Console.ReadLine();
    thrC.Abort();
    thrF.Abort();
    Console.ReadLine();
    }

    4.线程Join()方法
    Thread t = new Thread(aa);//aa()方法去执行其他代码
    t.IsBackground = true;
    t.Start();
    t.Join();//强制阻断其他线程执行,先执行当前线程
    Console.WriteLine("方法执行完毕");//这句代码会等到t这个线程执行完毕后才执行
    以上代码如果被另外一个线程调用时,t.Join()会阻断另外一个线程,等到t这个线程执行完毕后才执行

    5.委托的简单实用
    委托是用来保存一个方法的指针的
    如果方法的指针要被委托对象保存,那么这个方法的签名要和委托的签名一样。
    实用+=为委托对象追加方法
    public delegate void SayHi();
    SayHi s = new SayHi(Test);
    s+=Test1;
    s-=Test;
    s();

    6.GDI(图形设计接口)常用的方法
    //从panel1控件上创建一个画家Graphics对象
    using (Graphics g = Graphics.FromHwnd(this.panel1.Handle))
    {
    //g.DrawEllipse(Pens.Black, new Rectangle(0, 0, 100, 100));//画一个椭圆
    //g.DrawLine(Pens.Yellow, 10, 10, 100, 100);//画一条线
    //g.DrawArc(Pens.Black, new Rectangle(0, 0, 100, 100), 90, 90);//画一条弧线
    //g.DrawRectangle(Pens.Black,new Rectangle(0,0,100,200));//画一个矩形
    //g.DrawString("我是要写的字", new Font("微软雅黑", 12), new SolidBrush(Color.Red), new 
    PointF(10, 10));
    //g.FillEllipse(Brushes.Red, new Rectangle(0, 0, 100, 100));//用红色填充椭圆

    }
    //画水印
    using (Image img = new Bitmap(@"E:1.JPG"))
    {
    using (Graphics g = Graphics.FromImage(img))
    {
    using (Image img1 = new Bitmap(@"E:3.jpg"))
    {
    g.DrawImage(img1, 120, 177);
    }
    //g.DrawString("帅哥", new Font("微软雅黑", 30), new SolidBrush(Color.Red), new 
    PointF(10, 10));
    img.Save(@"E:2.jpg");
    }
    }

     
     
  • 相关阅读:
    IIS7中的几种身份鉴别方式(一)Basic身份验证
    IIS7中的几种身份鉴别方式(二)集成身份验证
    java集合
    SharePoint 2010中welcome page的设置细节
    SharePoint中使用Linq出现未将对象引用到实例化的解决方法
    SharePoint 2010中关于An error was encountered while retrieving the user profile的处理方式记录
    The Need for an Architectural Body of Knowledge
    The Softer Side of the Architect
    Event Receivers 学习小结
    使用SmtpClient发送带图片的邮件的代码实现
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3415083.html
Copyright © 2020-2023  润新知