zoukankan      html  css  js  c++  java
  • .NET多线程执行函数

    原因是DebugLZQ在写一个LINQ综合Demo的时候遇到了多线程,便停下手来整理一下。关于多线程的文章,园子里很多很多,因此关于多线程理论性的东西,LZ就不去多说了,这篇博文主要是用最简单的例子,总结下多线程调用函数的相关注意点,重点偏向应用和记忆。

    1.多线程调用无参函数                                                                                   

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    
    namespace 多线程
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("主线程开始");
                Thread t = new Thread(new ThreadStart(ShowTime));//注意ThreadStart委托的定义形式
                t.Start();//线程开始,控制权返回Main线程
                Console.WriteLine("主线程继续执行");
                //while (t.IsAlive == true) ;
                Thread.Sleep(1000);
                t.Abort();
                t.Join();//阻塞Main线程,直到t终止
                Console.WriteLine("--------------");
                Console.ReadKey();
            }
            static void ShowTime()
            {
                while (true)
                {
                    Console.WriteLine(DateTime.Now.ToString());               
                }
            }
        }
    }
    复制代码

    注意ThreadStart委托的定义如下:

    可见其对传递进来的函数要求是:返回值void,无参数。

    2.多线程调用带参函数(两种方法)                                                               

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    
    namespace 多线程2_带参数
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Main线程开始");
                Thread t = new Thread(new ParameterizedThreadStart(DoSomething));//注意ParameterizedThreadStart委托的定义形式
                t.Start(new string[]{"Hello","World"});
                Console.WriteLine("Main线程继续执行");
    
                Thread.Sleep(1000);
                t.Abort();
                t.Join();//阻塞Main线程,直到t终止
                Console.ReadKey();
            }
            static void DoSomething(object  s)
            {
                string[] strs = s as string[];
                while (true)
                {
                    Console.WriteLine("{0}--{1}",strs[0],strs[1]);
                }
            }
        }
    }
    复制代码

    注意ParameterizedThreadStart委托的定义如下:

    可见其对传入函数的要求是:返回值void,参数个数1,参数类型object

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    
    namespace 多线程2_带参数2
    {   
        class Program
        {
            static void Main(string[] args)
            {
                Guest guest = new Guest() 
                {
                 Name="Hello", Age=99
                };
                Thread t = new Thread(new ThreadStart(guest.DoSomething));//注意ThreadStart委托的定义形式
                t.Start();
    
                Thread.Sleep(1000);
                t.Abort();
                t.Join();//阻塞Main线程,直到t终止
                Console.ReadKey();
            }
        }
        //
        class Guest
        {
            public string Name { get; set; }
            public int Age { get; set; }
    
            public void DoSomething()
            {
                while (true)
                {
                    Console.WriteLine("{0}--{1}", Name, Age);
                }
            }
        }
    }
    复制代码

    这个还是使用ThreadStart委托,对方法进行了一个封装。

    两种方法,可随意选择,第一种貌似简洁一点。

    3.线程同步                                                                                              

    线程同步的方法有很多很多种volatile、Lock、InterLock、Monitor、Mutex、ReadWriteLock...

    这里用lock说明问题:在哪里同步,用什么同步,同步谁?

    首先感受下不同步会出现的问题:

    代码就是下面的代码去掉lock块。

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    
    namespace 多线程3_同步2
    {
        class Program
        {
            static object obj = new object();//同步用
    
            static int balance = 500;
    
            static void Main(string[] args)
            {
                Thread t1 = new Thread(new ThreadStart(Credit));
                t1.Start();
    
                Thread t2 = new Thread(new ThreadStart(Debit));
                t2.Start();
    
                Console.ReadKey();
            }
    
            static void Credit()
            {
                for (int i = 0; i < 15; i++)
                {
                    lock (obj)
                    {
                        balance += 100;
                        Console.WriteLine("After crediting,balance is {0}", balance);
                    }
                }
            }
            static void Debit()
            {
                for (int i = 0; i < 15; i++)
                {
                    lock (obj)
                    {
                        balance -= 100;
                        Console.WriteLine("After debiting,balance is {0}", balance);
                    }
                }
            }
        }
    }
    复制代码

    小结:多线程调用函数就是这样。在Winform中,控件绑定到特定的线程,从另一个线程更新控件,不应该直接调用该控件的成员,这个非常有用,下篇博文讲。

  • 相关阅读:
    Response生成注册验证码实现例子02
    Mysql 自增字段起始值auto_increment的修改方法
    elite核心库的加载方式及自动加载类库
    elite核心类库之事件类
    wamp速度缓慢的解决办法
    Dwzdialog中批量提交的问题处理
    PHP中缀表达式与逆波兰式的计算(用于工资项目等四则计算)
    PHP工资计算之逆波兰式
    elite核心类库之模板类
    PHP soap访问接口出错汇总及解决办法
  • 原文地址:https://www.cnblogs.com/armyfai/p/2766017.html
Copyright © 2011-2022 走看看