C# 如何让 多线程中每个线程间隔毫秒执行同一个方法?

问题描述

多线程的好处让效率提高很多倍,但是在某些情况下要求操作同一个方法的时候要求有间隔,这个间隔当然是毫秒级别的否则多线程的意义就体现不出来,本问题就是怎么让多线程中每个线程间隔毫秒执行同一个方法,测试代码如下:privatevoidbtnTest_Click(objectsender,EventArgse){TestManyThreadtest=newTestManyThread();test.Start();}

主要代码如下classTestManyThread{privatestaticDateTimelastOperyTime=DateTime.Now;privatestaticobjectlockTime=newobject();publicstaticDateTimeLastOperyTime{get{lock(lockTime){returnTestManyThread.lastOperyTime;}}set{lock(lockTime){TestManyThread.lastOperyTime=value;}}}publicvoidStart(){for(inti=0;i<10;i++){Threadth=newThread(newThreadStart(DoSomeThing));th.Name=i.ToString();th.SetApartmentState(ApartmentState.MTA);th.IsBackground=true;th.Start();}}///<summary>///多个线程做同一件事件但是要求每一个线程做同一件事件之间有毫秒级的间隔///</summary>privatevoidDoSomeThing(){TimeSpansp=DateTime.Now.Subtract(LastOperyTime);intintervalTime=100;//2个线程之间的间隔时间毫秒if(sp.TotalMilliseconds<intervalTime){System.Threading.Thread.Sleep(intervalTime);}LastOperyTime=DateTime.Now;stringinfo=string.Format("线程ID:{0},执行时间:{1}",Thread.CurrentThread.Name,DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss:ffff"));Console.WriteLine(info);}}

解决方案

解决方案二:
这个是输出的结果不符合要求.因为后面的毫秒没有间隔100以上,
解决方案三:
3296,33963496.....3996当然顺序不用控制,可以是329634963396只要最近2个线程的间的操作时间间隔大于100毫秒就行
解决方案四:
我也想学习这个,帮你顶上
解决方案五:
classTestManyThread{privatestaticDateTimelastOperyTime=DateTime.Now;privatestaticobjectlockTime=newobject();publicvoidStart(){for(inti=0;i<10;i++){Threadth=newThread(newThreadStart(DoSomeThing));th.Name=i.ToString();th.SetApartmentState(ApartmentState.MTA);th.IsBackground=true;th.Start();}}///<summary>///多个线程做同一件事件但是要求每一个线程做同一件事件之间有毫秒级的间隔///</summary>privatevoidDoSomeThing(){//...其他耗时操作//...//同步操作lock(lockTime){intintervalTime=100;//2个线程之间的间隔时间毫秒Thread.Sleep(Math.Max(0,intervalTime-(DateTime.Now-lastOperyTime).Milliseconds));stringinfo=string.Format("线程ID:{0},执行时间:{1}",Thread.CurrentThread.Name,DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss:ffff"));Console.WriteLine(info);lastOperyTime=DateTime.Now;}}}

解决方案六:
如果你只是要求100毫秒以上,并不是非常准确的100毫秒限制,那么可以用这个System.Threading.Timertimer=newSystem.Threading.Timer(newTimerCallback(doNext),null,0,100);

解决方案七:
你的Thread.Sleep完全放错了地方。一个“DoSomething”怎么管起线程的事情来了?你这个程序就是“摆着毛病而故意胡乱找理由”。你既然一齐“Thread.Start”,然后来纠结它们“应该间隔100毫秒再启动”,这不是自相矛盾嘛。故意找到一个无关的代码去纠结一个很浅显的需求,是为了什么呢?
解决方案八:

解决方案九:
http://www.baidu.com看下
解决方案十:
乱用线程
解决方案十一:
如果说要错开启动时间,一般人都会直截了当地写for(inti=0;i<10;i++){Threadth=newThread(newThreadStart(DoSomeThing));th.Name=i.ToString();th.SetApartmentState(ApartmentState.MTA);th.IsBackground=true;Thread.Sleep(i*100);th.Start();}

之类的代码。这里的问题是lz的习惯性的逻辑方式,似乎缺乏理科学生基本的素质训练。你的多个帖子都有类似的明显的故意“偷换逻辑”的习惯。
解决方案十二:
/*撸主,你应该是启动每个线程的时候,Sleep多少毫秒!而不是DoSomeThing做Sleep,DoSomeThing进行Sleep,是每个线程执行某个动作的时候,动作Sleep多少毫米!打个比方:10个人每个1分钟吃一个苹果(DoSomeThing)!你在DoSomeThing做Sleep,相当于苹果不是一口气吃完,而是吃的过程中暂停一下在继续吃*/for(inti=0;i<10;i++){Threadth=newThread(newThreadStart(DoSomeThing));th.Name=i.ToString();th.SetApartmentState(ApartmentState.MTA);th.IsBackground=true;th.Start();//Sleep一下}

解决方案十三:
线程调度的顺序是操作系统决定的不是你所能决定的了的你最多也只能设置线程的优先级就算你在启用线程的时候Thread.sleep(100)也有可能这个误差低于100毫秒因为操作系统完全可以在某些情况下将这个任务延迟执行反而去执行你后开启线程的任务。
解决方案十四:
windows不是实时操作系统,系统的定时器也没有这么高的精度,如果真要高精度的定时器,你可以看看windows核心编程
解决方案十五:
千万不要使用Thread.Sleep,用个计时器进行计时,使用AutoManualReset做线程间的同步。
解决方案:
可以使用一个AutoResetEvent来控制,初始为有信号,线程进入方法前等待这个信号.退出方法后SLEEP一段时间后设为不信号,就可以让下一个线程进入运行状态.
解决方案:
学习了
解决方案:
引用2楼QQ81867376的回复:

3296,33963496.....3996当然顺序不用控制,可以是329634963396只要最近2个线程的间的操作时间间隔大于100毫秒就行

是这个道理哦
解决方案:
期待有好的方法。
解决方案:

解决方案:
学些了,我也有类似的问题!
解决方案:
我国产剧怎么拍都没话说,把人人影视查封就说明心虚害怕
解决方案:
引用6楼sp1234的回复:

你的Thread.Sleep完全放错了地方。一个“DoSomething”怎么管起线程的事情来了?你这个程序就是“摆着毛病而故意胡乱找理由”。你既然一齐“Thread.Start”,然后来纠结它们“应该间隔100毫秒再启动”,这不是自相矛盾嘛。故意找到一个无关的代码去纠结一个很浅显的需求,是为了什么呢?

引用10楼sp1234的回复:

如果说要错开启动时间,一般人都会直截了当地写for(inti=0;i<10;i++){Threadth=newThread(newThreadStart(DoSomeThing));th.Name=i.ToString();th.SetApartmentState(ApartmentState.MTA);th.IsBackground=true;Thread.Sleep(i*100);th.Start();}

之类的代码。这里的问题是lz的习惯性的逻辑方式,似乎缺乏理科学生基本的素质训练。你的多个帖子都有类似的明显的故意“偷换逻辑”的习惯。

楼主,你应该听取这个大神的意见。
解决方案:
这种可行
解决方案:
classProgram{staticintdur=200;staticstringtm="";staticvoidMain(string[]args){for(inti=0;i<10;i++){vartd=newThread(newThreadStart(()=>{lock(tm){if(tm==""){Thread.Sleep(dur);}else{vart=DateTime.Now.Subtract(DateTime.Parse(tm));Thread.Sleep(dur-(int)t.TotalSeconds);}};DoSomeThing();}));td.Start();}Console.Read();}privatestaticvoidDoSomeThing(){tm=DateTime.Now.ToShortTimeString();stringinfo=string.Format("线程ID:{0},执行时间:{1}",Thread.CurrentThread.Name,DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss:ffff"));Console.WriteLine(info);Thread.Sleep(5000);}}

解决方案:

解决方案:
好久没来CSDN论坛了。。。,看到这个贴子,就回一下吧楼主,上面已有人说了你的逻辑不严密了,所以我就再说这个了,就给你一点简单的建议,想要控制线程之间严格执行一段代码或是函数,要将代码函数或里面的某一小段Lock起来,让某一时刻只能有一个线程进入!这样就可以所有访问该代码的线程都受到管控,否则你就会出现结果根本不是你想要的
解决方案:
引用4楼Forty2的回复:

classTestManyThread{privatestaticDateTimelastOperyTime=DateTime.Now;privatestaticobjectlockTime=newobject();publicvoidStart(){for(inti=0;i<10;i++){Threadth=newThread(newThreadStart(DoSomeThing));th.Name=i.ToString();th.SetApartmentState(ApartmentState.MTA);th.IsBackground=true;th.Start();}}///<summary>///多个线程做同一件事件但是要求每一个线程做同一件事件之间有毫秒级的间隔///</summary>privatevoidDoSomeThing(){//...其他耗时操作//...//同步操作lock(lockTime){intintervalTime=100;//2个线程之间的间隔时间毫秒Thread.Sleep(Math.Max(0,intervalTime-(DateTime.Now-lastOperyTime).Milliseconds));stringinfo=string.Format("线程ID:{0},执行时间:{1}",Thread.CurrentThread.Name,DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss:ffff"));Console.WriteLine(info);lastOperyTime=DateTime.Now;}}}

最开始就这些,测试还是一样.
解决方案:
引用6楼sp1234的回复:

你的Thread.Sleep完全放错了地方。一个“DoSomething”怎么管起线程的事情来了?你这个程序就是“摆着毛病而故意胡乱找理由”。你既然一齐“Thread.Start”,然后来纠结它们“应该间隔100毫秒再启动”,这不是自相矛盾嘛。故意找到一个无关的代码去纠结一个很浅显的需求,是为了什么呢?

对于你的教育放心我不是百分百的吸收,因为你不清楚别人的需求在这就开始教育人.线程启动的时候为什么要停止,你想过没有,另外这样简单的别人想不到?还是说下的我需求,10个线程开始工作,每个线程都要解析网页内容,仅仅是在提交的时候间隔不能低于500毫秒,解析很花时间,每个一个停止100毫秒浪费时间,仅仅在提交的时候需要间隔一下,明白了?????所以不要说别人偷换概念,什么逻辑什么...你的帖子的见过比较多,为什么总是在这个方面教育人呢,写出代码能说明问题,其次才是你这道理
解决方案:
使用Timer调用放在线程中的程序,Timer毫秒级启动,计数确定执行次数使用AutoResetEvent让线程阻塞等待上一个线程方法执行完成
解决方案:
用临界资源每个进入临界资源的线程,记录下离开临界资源时的时间,然后下个进入临界资源的线程,根据当前时间和上个线程离开时间的时间差,补足100ms的差距即可!!!!
解决方案:
不知道你是不是这个意思usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceConsoleApplication2{classProgram{staticvoidMain(string[]args){mydo();Console.ReadLine();}staticvoidmydo(){Action<string>action=(str)=>{Thread.Sleep(100);stringinfo=string.Format("do{0}:线程ID:{1},执行时间:{2}",str,Thread.CurrentThread.Name,DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss:ffff"));Console.WriteLine(info);};Task.Factory.StartNew(()=>action("1")).ContinueWith(antecendent=>action("2")).ContinueWith(antecendent=>action("3")).ContinueWith(antecendent=>action("4")).ContinueWith(antecendent=>action("5")).ContinueWith(antecendent=>action("6")).ContinueWith(antecendent=>action("7")).ContinueWith(antecendent=>action("8")).ContinueWith(antecendent=>action("9")).ContinueWith(antecendent=>action("10")).Wait();}}}

结果do1:线程ID:,执行时间:2015-04-24-23:56:04:1356do2:线程ID:,执行时间:2015-04-24-23:56:04:2406do3:线程ID:,执行时间:2015-04-24-23:56:04:3417do4:线程ID:,执行时间:2015-04-24-23:56:04:4428do5:线程ID:,执行时间:2015-04-24-23:56:04:5438do6:线程ID:,执行时间:2015-04-24-23:56:04:6459do7:线程ID:,执行时间:2015-04-24-23:56:04:7470do8:线程ID:,执行时间:2015-04-24-23:56:04:8491do9:线程ID:,执行时间:2015-04-24-23:56:04:9501do10:线程ID:,执行时间:2015-04-24-23:56:05:0522
解决方案:
使用AutoResetEvent让线程阻塞等待上一个线程方法执行完
解决方案:
你需要高精度定时器。Linux下叫做RealTimeClock、简称RTC,可以精确到CPU滴答。Windows下用QueryPerformanceFrequency+QueryPerformanceCounter可以精确到ms级
解决方案:
1.使用API计时器.2.用计时器来开新线程.
解决方案:
留言,学习。
解决方案:
多线程同步,你需要加locklock之后,你可以在被调用的函数体里面做逻辑判断是否需要延迟执行
解决方案:
这就好比,有个厕所堵了,前一个人上完厕所之后,后一个人必须等2分钟才能再上,否则就冒水了如果你多线程不做同步,那么相当于所有人互相都不认识,自己去判断别人是否上过了,那不现实,判断不了,互相没有沟通你需要有个看门的老大爷,定时往里面放人,有人了就不许进,间隔少于2分钟也不许进
解决方案:
这个可以吗?for(inti=0;i<10;i++){newThread(()=>{Trace.WriteLine(string.Format("Name:{0}Now:{1}",Thread.CurrentThread.Name,DateTime.Now.ToString("yyyy-MM-ddHH:mm:ss.ffff")));}){Name=i.ToString(),ApartmentState=ApartmentState.MTA,IsBackground=true}.Start();DateTimenow=DateTime.Now;TimeSpants=newTimeSpan(100*10000);SpinWait.SpinUntil(()=>{Thread.SpinWait(10);returnDateTime.Now-now>ts;});}

解决方案:
收藏学习一下,感谢各位大神!
解决方案:
学习了,很有用
解决方案:
没见过这样的用法。思路有问题~~线程可以同步
解决方案:
http://kb.cnblogs.com/page/42533/讲的很好
解决方案:
我是来学习的五一快乐
解决方案:
这个有问题,咋还置顶了。。。。。。
解决方案:
有点用多线程来做单线程的事的赶脚
解决方案:
向大神学习,留个记号
解决方案:
问题在于DataTime.Now的精度,最小精度16.5ms看到你的数据,有几个线程时间显示一样了么!你可以单独打印Data.Now.毫秒就可以看到效果了,不要打印所有时间
解决方案:
该回复于2015-09-30 23:53:14被版主删除
解决方案:
除非你做个锁,要么没办法
解决方案:
我不明白的是为什么操作同一个方法而且中间可以有数百毫秒这么长时间的间隔,还要分成多个线程来操作。。要不要吃点屎冷静一下再来写程序啊?

时间: 2024-08-03 23:37:19

C# 如何让 多线程中每个线程间隔毫秒执行同一个方法?的相关文章

多线程问题-新手求助关于Java多线程中启动线程问题

问题描述 新手求助关于Java多线程中启动线程问题 public class Example15_1 { /** * @param args */public static void main(String[] args) { // TODO Auto-generated method stub SpeakHello speakHello; SpeakNinhao speakNinhao; speakHello = new SpeakHello(); speakNinhao= new Speak

libssh2 多线程-libssh2在多线程中如何确保线程安全?

问题描述 libssh2在多线程中如何确保线程安全? 如题,我在csdn下载了一个别人编译好的libssh2库,但在多线程中使用的时候,总是运行一会儿就报异常说写入位置发生冲突,目前我只知道libssh2_session_init();这个函数是不安全的,多线程中需要加锁.我想请问下还有其他哪些函数是需要加锁的?只需要告诉我下面这些函数哪些需要加锁就可以了. 1.libssh2_session_set_timeout 2.libssh2_session_startup 3.libssh2_ses

C/C++中退出线程的四种解决方法_C 语言

退出线程可以有四种方法: 1.线程函数的return返回(最好这样):其中用线程函数的return返回, 而终止线程是最安全的, 在线程函数return返回后, 会清理函数内申请的类对象, 即调用这些对象的析构函数. 然后会自动调用 _endthreadex()函数来清理 _beginthreadex(...)函数申请的资源(主要是创建的tiddata对象). 2.调用 _endthreadex()函数 或 ExitThread()函数(最好不要):如果使用这两种方法退出线程, 则不会执行线程函

线程40毫秒执行一次 占用CPU35%左右 正常吗?

问题描述 线程中的代码ImageBrushib=newImageBrush(newBitmapImage(newUri("pack://application:,,,/beijindonghua/背景视频("+i+").jpg")));grid_bg.Background=ib;i++;if(i==749){i=1;} 解决方案 解决方案二:视频还是不要做得这么非主流.还是老老实实用视频插件.解决方案三:我是做软件背景的..解决方案四:引用1楼wawd74520的回

解析Java线程编程中的线程安全与synchronized的使用_java

一.什么时候会出现线程安全问题? 在单线程中不会出现线程安全问题,而在多线程编程中,有可能会出现同时访问同一个资源的情况,这种资源可以是各种类型的的资源:一个变量.一个对象.一个文件.一个数据库表等,而当多个线程同时访问同一个资源的时候,就会存在一个问题: 由于每个线程执行的过程是不可控的,所以很可能导致最终的结果与实际上的愿望相违背或者直接导致程序出错. 举个简单的例子: 现在有两个线程分别从网络上读取数据,然后插入一张数据库表中,要求不能插入重复的数据. 那么必然在插入数据的过程中存在两个操

详解Java编程中对线程的中断处理_java

1. 引言 当我们点击某个杀毒软件的取消按钮来停止查杀病毒时,当我们在控制台敲入quit命令以结束某个后台服务时--都需要通过一个线程去取消另一个线程正在执行的任务.Java没有提供一种安全直接的方法来停止某个线程,但是Java提供了中断机制. 如果对Java中断没有一个全面的了解,可能会误以为被中断的线程将立马退出运行,但事实并非如此.中断机制是如何工作的?捕获或检测到中断后,是抛出InterruptedException还是重设中断状态以及在方法中吞掉中断状态会有什么后果?Thread.st

JAVA多线程摘要之线程启动

线程的创建和启动 java语言已经内置了多线程支持,所有实现Runnable接口的类都可被启动一 个新线程,新线程会执行该实例的run()方法,当run()方法执行完毕后,线程就 结束了.一旦一个线程执行完毕,这个实例就不能再重新启动,只能重新生成一 个新实例,再启动一个新线程. Thread类是实现了Runnable接口的一个实例,它代表一个线程的实例,并且 ,启动线程的唯一方法就是通过Thread类的start()实例方法: Thread t = new Thread(); t.start(

c#-C#中利用线程触发button事件后,是否可在button 中Abort线程?

问题描述 C#中利用线程触发button事件后,是否可在button 中Abort线程? C#中利用线程触发button事件后,是否可在button 中Abort线程? 解决方案 可以是可以,但是这样做容易造成意想不到的情况,比如资源泄露或者文件写入错误或者崩溃. 最好让线程自己退出. 解决方案二: btn 中应该定义的是执行的方法,你用线程 执行方法就行了,干嘛 非得通过 btn事件来执行方法? 解决方案三: 一般不会这样去结束一个线程,通常的做法是线程里面加一个循环,循环条件设置为Flag,

C#中的线程(三)多线程

Keywords:C# 线程Source:http://www.albahari.com/threading/Author: Joe AlbahariTranslator: Swanky WuPublished: http://www.cnblogs.com/txw1958/Download:http://www.albahari.info/threading/threading.pdf    第三部分:使用多线程   单元模式和Windows Forms 单元模式线程是一个自动线程安全机制,