c# for循环中创建线程执行问题
先执行以一个简单的示例:
static void Main(string[] args) { List<int> taskConsumes = new List<int>() { 1,2,3,4,5}; for (int i = 0; i < taskConsumes.Count; i++) { new Task(() => { TaskMethod(taskConsumes[i]); }).Start(); } Console.ReadLine(); } public static void TaskMethod(int index) { Console.WriteLine(index); }
执行结果:
直接异常了,按照常理不应该呀,我们再将原理的代码改一下看看结果如何
我们先来创建执行线程代码,然后在写输出代码:
static void Main(string[] args) { new Task(() => { TaskMethod(1); }).Start(); Console.WriteLine("输出内容"); Console.ReadLine(); }
输出结果:
由此我们可以得出一个结论,就是:创建执行Task.Run()
是在另外一个子线程中执行的,他的创建+执行需要消耗一定的时间,而主线程方法是不会受Task的影响,他会直接执行
因此,我们最初的代码中,for循环 0到taskConsumes.Count
,很快就会执行完成。当他执行完成最后的 i 其实不是taskConsumes.Count-1(
因为for是 i++形式),而是
所以,在执行子线程的时候,其实就是去拿taskConsumes[5
],准定就超出索引异常了。
那现在我们如果不想让程序出错的执行,给他改一下代码:
static void Main(string[] args) { List<int> taskConsumes = new List<int>() { 1, 2, 3, 4, 5 }; for (int i = 0; i < taskConsumes.Count; i++) { int indexI = i; new Task(() => { TaskMethod(taskConsumes[indexI]); }).Start(); } Console.ReadLine(); }
执行结果:
这样,我们在for中创建一个临时变量indexI
,每个工作域中的i都赋予了局部变量indexI,Task中的变量就是局部变量indexI
了,而不是for
的全部变量i,程序也就达到了我们想要的效果了(另外Task子线程中执行顺序也不是顺序执行的)。
到此这篇关于c# for循环中创建线程执行问题的文章就介绍到这了,更多相关for循环中创建线程执行内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
相关推荐
-
C#中foreach循环对比for循环的优势和劣势
前言 循环语句为众多程序员们提供了很大的便利,有while.do...while.for和 foreach.而且foreach语句很简洁,但是它的优点不仅仅在于此,它的效率也是最高的.本文将详细给大家关于C#中foreach循环对比for循环的优势和劣势,下面话不多说了,来一起看看详细的介绍吧. 一.foreach循环的优势 C#支持foreach关键字,foreach在处理集合和数组相对于for存在以下几个优势: 1.foreach语句简洁 2.效率比for要高(C#是强类型检查,for循环对
-
C#使用for循环移除HTML标记
移除一段文字中的HTML标记,以消除其中包含的样式和段落等,最常用的办法可能就是正则表达式了.但是请注意,正则表达式并不能处理所有的HTML文档,所以有时采用一个迭代的方式会更好,如for循环. 看下面的代码: using System; using System.Text.RegularExpressions; /// <summary> /// Methods to remove HTML from strings. /// </summary> public static c
-
浅谈C#中的for循环与foreach循环
for循环和foreach循环其实可以算得上是从属关系的,即foreach循环是可以转化成for循环,但是for循环不一定能转换成foreach循环. 下面简单介绍一下两种循环: 1.for循环 代码格式: for(表达式1;循环条件;表达式2) { 循环体 } 代码含义: 首先运行表达式1; 然后判断条件是否为真,如果为真,则执行循环体,执行完后再运行表达式2: 接着再判断循环条件--直到循环条件为假才会结束循环. 注意事项: 表达式1:可以是任何代码,一定会执行且只会执行一次: 表达式2:可
-
C# for循环的经典案例集锦
由于for循环可以通过控制循环变量的初始值和循环结束条件来改变遍历的区间,所以在排序或者遍历的时候,利用for循环就比较简单,以下是本人学习后得到的一些总结案例. 1.排序的应用 1)交换排序:通过取出的数和该数位置后面剩余的其他数逐一进行比较,将最大的或者最小的一个数放在一组数的首位,然后再将第二大的数放在第二位,依次排完所有的数. for(int i = 0; i < (num.length - 1); i ++) { for(int j = i + 1; j < num.length;
-
C#中Foreach循环遍历的本质与枚举器详解
目录 前言 1.创建一个控制台应用程序 2.编写测试代码并分析 3.总结 前言 对于C#里面的Foreach学过 语言的人都知道怎么用,但是其原理相信很多人和我一样都没有去深究.刚回顾泛型讲到枚举器让我联想到了Foreach的实现,所以进行一番探究,有什么不对或者错误的地方大家多多斧正. 1.创建一个控制台应用程序 2.编写测试代码并分析 在Program类中写一个foreach循环 class Program { static void Main(string[] args) { List p
-
c#中list.FindAll与for循环的性能对比总结
前言 最近在网上看到一篇文章,里面说到:List<T>.FindAll的效率竟然比for循环还差,下面是文章的截图: 以上就是baidu出来的一篇文章,让我惊诧不已,因为在AI模块我已经使用了很多FindAll.但是,上文的结论是真的吗? 我在上文代码基础上增加了多次测试的代码: 得到了如下结果: .Net2.0, visual studio 执行1,1,10, 100,1000次: .Net4.1, visual studio 执行1,1,10, 100,1000次: Unity 先预处理再
-
C# winform循环播放多个视频
本文实例为大家分享了winform循环播放多个视频的具体代码,供大家参考,具体内容如下 环境: vs2015 +winform 首先,vs自带组件很方便,所以,用windowMediaplayer组件,如果做单曲循环播放的话,加个属性: axWindowsMediaPlayer1.settings.autoStart = true; //设置自动播放 axWindowsMediaPlayer1.settings.setMode("loop", true); //设置循环播放 言归正传:
-
C# 9.0新特性——扩展方法GetEnumerator支持foreach循环
1.介绍 我们知道,我们要使一个类型支持foreach循环,就需要这个类型满足下面条件之一: 该类型实例如果实现了下列接口中的其中之一: System.Collections.IEnumerable System.Collections.Generic.IEnumerable<T> System.Collections.Generic.IAsyncEnumerable<T> 该类型中有公开的无参GetEnumerator()方法,且其返回值类型必须是类,结构或者接口,同时返回值类型
-
c# for循环中创建线程执行问题
先执行以一个简单的示例: static void Main(string[] args) { List<int> taskConsumes = new List<int>() { 1,2,3,4,5}; for (int i = 0; i < taskConsumes.Count; i++) { new Task(() => { TaskMethod(taskConsumes[i]); }).Start(); } Console.ReadLine(); } public
-
SpringBoot 项目中创建线程池
前言: 前两天做项目的时候,想提高一下插入表的性能优化,因为是两张表,先插旧的表,紧接着插新的表,一万多条数据就有点慢了 后面就想到了线程池ThreadPoolExecutor,而用的是Spring Boot项目,可以用Spring提供的对ThreadPoolExecutor封装的线程池ThreadPoolTaskExecutor,直接使用注解启用 使用步骤: 先创建一个线程池的配置,让Spring Boot加载,用来定义如何创建一个ThreadPoolTaskExecutor,要使用@Con
-
Java中一个线程执行死循环有什么后果
假设有两个线程在并发运行,一个线程执行的代码中含有一个死循环如:while(true)....当该线程在执行while(true)中代码时,另一个线程会有机会执行吗? 示例代码(代码来源于互联网) public class Service { Object object1 = new Object(); public void methodA() { synchronized (object1) { System.out.println("methodA begin"); boolea
-
如何在Java中创建线程通信的四种方式你知道吗
目录 1.1 创建线程 1.1.1 创建线程的四种方式 1.1.2 Thread类与Runnable接口的比较 1.1.3 Callable.Future与FutureTask 1.2 线程组和线程优先级 1.3 Java线程的状态及主要转化方法 1.4 Java线程间的通信 1.4.1 等待/通知机制 1.4.2 信号量 1.4.3 管道 总结 1.1 创建线程 1.1.1 创建线程的四种方式 [1]继承Thread类 [2]实现Runnable接口 [3]实现Callable,获取返回值 [
-
Java并发编程示例(一):线程的创建和执行
开门见山 在IT圈里,每当我们谈论并发时,必定会说起在一台计算机上同时运行的一系列线程.如果这台电脑上有多个处理器或者是一个多核处理器,那么这时是实实在在的"同时运行":但是,如果计算机只有一个单核处理器,那么这时的"同时运行"只是表象而已. 所有的现代操作系统全部支持任务的并发执行.你可以边听音乐,边上网看新闻,还不耽误首发电子邮件.我们可以说,这种并发是 进程级并发 .在进程内部,我也可以看到有许许多多的并发任务.我们把运行在一个进程里面的并发任务称 线程. 和
-
Java 并发编程中如何创建线程
简介 线程是基本的调度单位,它被包含在进程之中,是进程中的实际运作单位,它本身是不会独立存在.一个进程至少有一个线程,进程中的多个线程共享进程的资源. Java中创建线程的方式有多种如继承Thread类.实现Runnable接口.实现Callable接口以及使用线程池的方式,线程池将在后面文章中单独介绍,这里先介绍另外三种方式. 继承Thread类 优点:在run方法里可以用this获取到当前线程. 缺点:由于Java不支持多继承,所以如果继承了Thread类后就不能再继承其他类. public
-
node事件循环中事件执行的顺序
目录 事件循环 浏览器环境事件循环 node环境事件循环 六个阶段 (1) setTimeout 和 setImmediate (2) process.nextTick 练习例子 总结: 事件循环 在浏览器环境下我们的js有一套自己的事件循环,同样在node环境下也有一套类似的事件循环. 浏览器环境事件循环 首先,我们先来回顾一下在浏览器的事件循环: 总结来说: 首先会运行主线程的同步代码,每一行同步代码都会被压入执行栈,每一行异步代码会压入异步API中(如:定时器线程.ajax线程等:),在执
-
Java中终止线程的方法详解
Java中终止线程的方式主要有三种: 1.使用stop()方法,已被弃用.原因是:stop()是立即终止,会导致一些数据被到处理一部分就会被终止,而用户并不知道哪些数据被处理,哪些没有被处理,产生了不完整的"残疾"数据,不符合完整性,所以被废弃.So, forget it! 2.使用volatile标志位 看一个简单的例子: 首先,实现一个Runnable接口,在其中定义volatile标志位,在run()方法中使用标志位控制程序运行 public class MyRunnable i
-
Java中实现线程的三种方式及对比_动力节点Java学院整理
Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行体. (2)创建Thread子类的实例,即创建了线程对象. (3)调用线程对象的start()方法来启动该线程. package com.thread; public class FirstThreadTest extends Thread{ int i = 0; //重写run方法,run方法的方
-
Java并发编程之创建线程
先讲述一下Java中的应用程序和进程相关的概念知识,然后再阐述如何创建线程以及如何创建进程.下面是本文的目录大纲: 一.Java中关于应用程序和进程相关的概念 二.Java中如何创建线程 三.Java中如何创建进程 一.Java中关于应用程序和进程相关的概念 在Java中,一个应用程序对应着一个JVM实例(也有地方称为JVM进程),一般来说名字默认为java.exe或者javaw.exe(windows下可以通过任务管理器查看).Java采用的是单线程编程模型,即在我们自己的程序中如果没有主动创
随机推荐
- AngularJS模块管理问题的非常规处理方法
- Angular.Js中ng-include指令的使用与实现
- mac下安装和配置mongodb的步骤详解
- SQLServer2005 没有日志文件(*.ldf) 只有数据文件(*.mdf) 恢复数据库的方法
- vue中如何引入jQuery和Bootstrap
- PERL脚本 学习笔记
- python下函数参数的传递(参数带星号的说明)
- ASP.NET 2.0中的页面输出缓存
- 完美解决thinkphp验证码出错无法显示的方法
- mysql_fetch_row,mysql_fetch_array,mysql_fetch_assoc的区别
- C#中构造函数和析构函数用法实例详解
- android使用url connection示例(get和post数据获取返回数据)
- 使用gulp搭建本地服务器并实现模拟ajax
- 使用Raygun对Node.js应用进行错误处理的方法
- Linux Nginx 配置SSL访问实例详解
- 初窥JQuery(一)jquery选择符 必备知识点
- java序列化与反序列化操作实例分析
- WIN8.1下搭建PHP5.6环境
- android利用xml实现分割线
- 基于webpack.config.js 参数详解