zoukankan      html  css  js  c++  java
  • .Net多线程

      关于多线程处理,根据自己的学习做了一下总结,算是复习用,下面主要贴一些实例Demo。看此博客建议先将.Net委托(拉姆达表达式)先学习一下,否则,看起来可能比较吃力,至少我是这样的。

     为了清晰,我把标题做了红字黄底加粗显示。

      1,启动线程调用无参无返回值的方法

    Console.WriteLine("主线程开始");
    Thread t1 = new Thread(new ThreadStart(Test1));
    //可以通过IsBackground=true,把指定线程设置为后台线程。
    //默认创建的进程都是“前台线程”,只有当所有“前台线程”都执行完毕后“进程”才会结束。
    //后台线程在所有前台线程执行完毕后,自动退出。
    t1.IsBackground = true;
    t1.Start();
    //在哪个线程中执行,就阻塞了哪个线程,那个线程要等待t1线程执行完毕后,然后才会继续。
    //如果不理解,把t1.Join()注掉观察结果
    //Join可以在在参数中设置阻塞时间,例如t1.Join(1000)
    t1.Join();
    Console.WriteLine("主线程结束");
    Console.Read();

      2,启动线程调用有参数无返回值的方法

        ①利用预定义的函数调用

    Console.WriteLine("主线程开始");
    Thread t2 = new Thread(new ParameterizedThreadStart(Test2));
    t2.Start(100);
    Console.WriteLine("主线程结束");
    Console.Read();

        ②将函数封装到类中,演变成调用无参数无返回值的方法

    MyClass mc = new MyClass();
    mc.Num = 100;
    Thread t3 = new Thread(new ThreadStart(mc.Test3));
    t3.Start();
    Console.Read();

    class MyClass

    {

        private int num;

        public int Num

        {

            get { return num; }

            set { num = value; }

        }

     

        public void Test3()

        {

            int result = 0;

            for (int i = 0; i < this.Num; i++)

            {

                result += i;

            }

            Console.WriteLine(result);

        }

    }

      3,启动线程调用有参数有返回值得方法

        ①BackgroundWorker实现

    BackgroundWorker backWorker = new BackgroundWorker();
    backWorker.DoWork += backWorker_DoWork;
    backWorker.RunWorkerCompleted += backWorker_RunWorkerCompleted;
    backWorker.RunWorkerAsync(new int[] { 100 });
    Console.Read();

    static void backWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        if (e.Argument != null)
        {
            int[] arr = e.Argument as int[];
            e.Result = Test4(arr[0]);
        }
    }

    private static void backWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        Console.WriteLine(e.Result);
    }

        ②异步委托调用实现

          A,BeginInvoke&EndInvke的方式实现

    Console.WriteLine("主线程开始");
    MyDel md = new MyDel(Test4);
    IAsyncResult asyResult = md.BeginInvoke(100, null, null);
    for (int i = 0; i < 10; i++)
    {
        Console.WriteLine("主线程进行中..." + i);
    }
    //调用EndInvoke会阻塞线程,等待异步委托执行完毕。
    int sum = md.EndInvoke(asyResult);
    Console.WriteLine(sum);
    Console.WriteLine("主线程结束");
    Console.Read();

          B,回调的方式实现

    MyDel md = new MyDel(Test4);
    IAsyncResult asyResult = md.BeginInvoke(100, CallBack, "Test");
    Console.WriteLine("主线程继续");
    Console.Read();

    private static void CallBack(IAsyncResult res)
    {
        Console.WriteLine("回调函数执行中");
        AsyncResult ar = res as AsyncResult;
        int sum = ((MyDel)ar.AsyncDelegate).EndInvoke(ar);
        Console.WriteLine("返回值是:"+sum);
    }

      4,终止线程

    if (t1 != null)
    {
        t1.Abort();
    }

      5,跨线程访问控件

    ////如果不关闭跨线程访问控件检查,会抛出异常
    //Thread t2 = new Thread(new ThreadStart(() =>
    //{
    //    this.textBox1.Text = "Hi";
    //}));
    //t2.IsBackground = true;
    //t2.Start();
    Thread t1 = new Thread(new ThreadStart(() =>
    {
        //利用控件的Invoke方法,将控件的操作放到创建空间的线程中进行
        this.textBox1.Invoke(new Action<string>(UpdateText), "hello");
    }));
    t1.IsBackground = true;
    t1.Start();

      6,线程池

    Console.WriteLine("Main thread ID:" + Thread.CurrentThread.ManagedThreadId);
    ThreadPool.QueueUserWorkItem(new WaitCallback((obj) =>
    {
        Console.WriteLine("Thread 1 ID:" + Thread.CurrentThread.ManagedThreadId);
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine(".");
            Thread.Sleep(500);
        }
    }));
    ThreadPool.QueueUserWorkItem(new WaitCallback((obj) =>
    {
        Console.WriteLine("Thread 1 ID:" + Thread.CurrentThread.ManagedThreadId);
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("*");
            Thread.Sleep(500);
        }
    }));
    ThreadPool.QueueUserWorkItem(new WaitCallback((obj) =>
    {
        Console.WriteLine("Thread 1 ID:" + Thread.CurrentThread.ManagedThreadId);
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("=");
            Thread.Sleep(500);
        }
    }));
    Console.WriteLine("主线程继续");
    Console.Read();

      7,锁机制

    static long max = 100000;
    static long idx = 0;
    static readonly object objSync = new object();
    static void Main(string[] args)
    {
        Thread t1 = new Thread(new ThreadStart(() =>
        {
            for (int i = 0; i < max; i++)
            {
                lock (objSync)
                {
                    idx++;
                }
            }            
        }));
        t1.IsBackground = true;
        t1.Start();
        for (int i = 0; i < max; i++)
        {
            lock(objSync)
            {
                idx--;
            }
        }
        t1.Join();
        Console.WriteLine("最终idx="+idx);
        Console.Read();

      8,单线程造成界面假死多线程解决

    Random rd = new Random();

    ////单线程,线程一直在做死循环,无法更新界面

    //while (true)

    //{

    //    label1.Text = rd.Next(0, 10).ToString();

    //    label2.Text = rd.Next(0, 10).ToString();

    //    label3.Text = rd.Next(0, 10).ToString();

    //    Thread.Sleep(300);

    //}  

     

    //开启一个线程专门处理界面显示

    t1 = new Thread(new ThreadStart(() =>

    {

        while (true)

        {

            label1.Text = rd.Next(0, 10).ToString();

            label2.Text = rd.Next(0, 10).ToString();

            label3.Text = rd.Next(0, 10).ToString();

            Thread.Sleep(300);

        }

    }));

    t1.IsBackground = true;

    t1.Start();

  • 相关阅读:
    Find the Smallest K Elements in an Array
    Count of Smaller Number
    Number of Inversion Couple
    Delete False Elements
    Sort Array
    Tree Diameter
    Segment Tree Implementation
    Java Programming Mock Tests
    zz Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)
    Algorithm about SubArrays & SubStrings
  • 原文地址:https://www.cnblogs.com/aaron-song/p/4358835.html
Copyright © 2011-2022 走看看