• .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();

  • 相关阅读:
    新书推荐——《How We Test Software at Microsoft》
    [ZZ]采访与书摘:使用C#进行基于模型的软件测试和分析
    Adding Different Types of Data Sources to a Web Test
    [ZZ]为什么传统的自动化测试工具会扼杀敏捷?
    很久没有这么High了
    留图以纪念这次地震
    white——Automate windows applications
    WatiN、Wax、WatiN Test Recorder开源自动化测试框架
    绝版的T61普屏
    有感于公司搬家
  • 原文地址:https://www.cnblogs.com/aaron-song/p/4358835.html
Copyright © 2020-2023  润新知