当前位置: 首页 > news >正文

.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中,控件绑定到特定的线程,从另一个线程更新控件,不应该直接调用该控件的成员,这个非常有用,下篇博文讲。

转载于:https://www.cnblogs.com/armyfai/archive/2012/11/12/2766017.html

相关文章:

  • jdk1.5新特性2之动态参数列表
  • 进阶第二十一课 Python多线程
  • 【ASP】简单Url编码和Url解码实例
  • Flannel网络组件部署
  • EXCEL应用技巧:如何在每行下插入一个空行
  • docker 关闭镜像后,容器无法启动---Conflict. The container nam
  • 【翻译】Nova国际化
  • stm 常用头文件
  • mysql中去重复记录
  • 开源母语编程 说明 (持续更新)
  • 你不懂js系列学习笔记-作用域和闭包- 03
  • Mac 平台下功能强大的Shimo软件使用指南
  • 初学redis分页缓存方法实现
  • Redis 安装及配置
  • chroot 命令小记
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • C++入门教程(10):for 语句
  • Codepen 每日精选(2018-3-25)
  • create-react-app项目添加less配置
  • css选择器
  • ES10 特性的完整指南
  • Flex布局到底解决了什么问题
  • Fundebug计费标准解释:事件数是如何定义的?
  • IDEA 插件开发入门教程
  • javascript面向对象之创建对象
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • java中具有继承关系的类及其对象初始化顺序
  • Laravel Telescope:优雅的应用调试工具
  • nginx 负载服务器优化
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • SpringCloud集成分布式事务LCN (一)
  • springMvc学习笔记(2)
  • Twitter赢在开放,三年创造奇迹
  • yii2权限控制rbac之rule详细讲解
  • 编写高质量JavaScript代码之并发
  • 大数据与云计算学习:数据分析(二)
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 订阅Forge Viewer所有的事件
  • 跳前端坑前,先看看这个!!
  • 学习使用ExpressJS 4.0中的新Router
  • 用Canvas画一棵二叉树
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 主流的CSS水平和垂直居中技术大全
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #pragma data_seg 共享数据区(转)
  • (Java数据结构)ArrayList
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (分享)自己整理的一些简单awk实用语句
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (接口自动化)Python3操作MySQL数据库
  • (南京观海微电子)——I3C协议介绍
  • (万字长文)Spring的核心知识尽揽其中
  • (转)shell调试方法