我爱我老婆

最新评论

共2页: 1 2 下一页 
烈火★寒冰 2010-08-17 00:24
分析透彻,观点各异。学习学习
Pvistely 2009-05-20 00:10
我也来插一腿,呵呵
我看了下Thread.Timer跟Windows.Forms.Timer的代码,发现WinForm的Timer是用SetTimer这个API直接创建TIMER的,
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern IntPtr SetTimer(HandleRef hWnd, int nIDEvent, int uElapse, IntPtr lpTimerFunc);

但Thread.Timer是用.NET底层创建的Timer,具体怎么样我也没深入分析,
Thread.Timer是基于TimerBase对象来做计时器管理,
internal void AddTimer(TimerCallback callback, object state, uint dueTime, uint period, ref StackCrawlMark stackMark)
{
if (callback == null)
{
throw new ArgumentNullException("TimerCallback");
}
_TimerCallback callback2 = new _TimerCallback(callback, state, ref stackMark);
state = callback2;
this.AddTimerNative(state, dueTime, period, ref stackMark);
this.timerDeleted = 0;
}


其中的AddTimerNative就是用来增加新的计时器,应该就是线程池中的操作


我在用DataGridView或其他Grid时做数据绑定操作确实会出现莫名其妙的错误,

因此也在找SLEEP、THREAD.TIMER及WINFORM.TIMER的比较,希望能有个结果
tssing 2009-03-12 20:24
@小猴子
DataGridView+bindingsource....
用线程会出错,,而用timer不会。。。
小猴子 2009-03-12 17:09
@韦恩卑鄙

好象使用TIMER的时候会堵塞主线程,感受最深的就是DELPHI的TIMER。
半死不活其实不是死了,是卡在那里。弄得用户很不舒服!
在VS里面,还很少用这个东西!还是比较习惯用THREAD,更方便,更自由点。
tssing 2009-03-12 15:35
受教了
gxh973121 2009-03-12 15:33
--引用--------------------------------------------------
tssing: 讨论这么多呀
timer和thread是不一样的概念,
timer是单线程,,thread是多线程,,
--------------------------------------------------------
System.timer 只是对thread 进行了下包装,是一样的
tssing 2009-03-12 15:13
讨论这么多呀
timer和thread是不一样的概念,
timer是单线程,,thread是多线程,,
韦恩卑鄙 2009-03-12 12:37
--引用--------------------------------------------------
小猴子: System.Timer
已经很少用这个东西了,基本都是用THREAD。TIMER不好用,除非任务很简单,否则经常挂起在那里,半死不活的。
--------------------------------------------------------
threading.timer 设置为定时触发模式 怎么会半死不活呢?


-----------
eaglet
定时器确实是需要调整的,我用 Sleep 的方法做过一个定时器,Tick 是 100ms,运行几天以后误差依然在1s以内。如果不调整,误差会放大到10秒以上,我实测过。
---------------

刚才看错了。 调整其实也可以从开始任务时候的时间值和当前时间值的差来计算调整。那样误差更小。
小猴子 2009-03-12 10:13
System.Timer
已经很少用这个东西了,基本都是用THREAD。TIMER不好用,除非任务很简单,否则经常挂起在那里,半死不活的。
NingDev 2009-03-11 23:16
学习,以前用过System.Timer 开触发事件,但是有时会将线程挂起,引出一些问题,后来就改用System.Threading 。
eaglet 2009-03-11 18:36
另外楼上讨论的这些定时方法都不是很精确的,如果要更精确的,建议用多媒体定时器。那些音频视频的解码都是通过多媒体定时器来控制的。
eaglet 2009-03-11 18:32
定时器确实是需要调整的,我用 Sleep 的方法做过一个定时器,Tick 是 100ms,运行几天以后误差依然在1s以内。如果不调整,误差会放大到10秒以上,我实测过。
上不了岸的鱼{ttzhang} 2009-03-11 17:40
学习
LT 2009-03-11 16:21
以前看几个老外探讨过这个问题 似乎是com 线程模型不兼容导致
--------------------------------------
这个有点道理,谢谢韦恩卑鄙,接口试过几个,没成功。
韦恩卑鄙 2009-03-11 16:18
--引用--------------------------------------------------
LT: --------------------------------------------------
韦恩卑鄙: WebBrowser 核心是 进程外com, shdocvw32 根本不是本进程的东西 想传递可太难了。

而你说的 windows form 上的timers.timer 本身受制于winform的sta ,根本没有在多线程环境下运行, 所以并不是timer和thread有所分别 而是你的winform 程序取消了timer的多线程性


--------------------------------------------------------
哦,但webBrowser是一个WebBrowser ActiveX 控件托管包装,一个合法的运行时托管对象为什么就不能传递给线程中,这逻辑上多少有点讲不通啊
--------------------------------------------------------

以前看几个老外探讨过这个问题 似乎是com 线程模型不兼容导致
似乎不用对象传递 用 IHTMLWindow 传递就可以避免

原理我还真不懂 毕竟不是搞c++的
LT 2009-03-11 16:15
--------------------------------------------------
韦恩卑鄙: WebBrowser 核心是 进程外com, shdocvw32 根本不是本进程的东西 想传递可太难了。

而你说的 windows form 上的timers.timer 本身受制于winform的sta ,根本没有在多线程环境下运行, 所以并不是timer和thread有所分别 而是你的winform 程序取消了timer的多线程性


--------------------------------------------------------
哦,但webBrowser是一个WebBrowser ActiveX 控件托管包装,一个合法的运行时托管对象为什么就不能传递给线程中,这逻辑上多少有点讲不通啊
韦恩卑鄙 2009-03-11 16:14
--引用--------------------------------------------------
bright.yeml: 韦恩
不知道怎么跟你说
jeffery 的确是个大大牛
不过他说的这句应该是个普遍性的规则,实际应用的情况有所不同
--------------------------------------------------------
就好像 上次老赵说 list<T>容量翻倍 的损耗可以无视一样, 这个不是大牛说怎样都怎样 而是从理论上从实践上都能证明的。

一次26分钟的测试就能说明问题? 这中间只要引发一次gc 整个测试数据都变成废纸了
bright.yeml 2009-03-11 16:11
韦恩
不知道怎么跟你说
jeffery 的确是个大大牛
不过他说的这句应该是个普遍性的规则,实际应用的情况有所不同
韦恩卑鄙 2009-03-11 16:10
--引用--------------------------------------------------
DataFlow: @韦恩卑鄙
3.还是那句话,不要迷信什么大牛,数据才是王道。
--------------------------------------------------------
跟你说你延长10倍 你自己都不敢看数据了?
1。sleep 表不准 timer表准 这个你还是没解决 而我第一篇回复就告诉你解决方案了
每次sleep都需要计算好执行部分的耗费时间 做好偏移
韦恩卑鄙 2009-03-11 16:02
--引用--------------------------------------------------
bright.yeml: 。net内置了3个timer
forms里面的timer是基于UI线程的,如果timer的tick里面要执行长任务,会影响界面的 响应,而且我发现在多线程里面,这个timer会不出发tick事件,不知道为什么

而另外两个timer,都是基于线程池的
所以如果线程池的线程负荷很大,或者线程池被限制到很小(比如我的程序里设置了可以由用户选择线程数)的话,这两个timer会由于拿不到线程而没办法正常执行

所以我选择自己写了一个timer

代码如下
/// &lt;summary&gt;
/// 自定义timer
/// 因为forms.timer在多线程里面不会动
/// system.timer和thread里面的timer试用了线程池,
/// 由于我的程序会占光线程池里面的线程,所以只能自己写一个
/// &lt;/summary&gt;
public class Timer
{
private bool stopped;
private volatile bool elapsed;

public bool Elapsed
{
get { return elapsed; }
set { elapsed = value; }
}
private int interval;

public int Interval
{
get { return interval; }
set { interval = value; }
}
public Timer()
{
}
public Timer(int miliSeconds)
{
this.interval = miliSeconds;
}
public void Start()
{
while (true)
{
Thread.Sleep(this.interval);
if (this.stopped)
{
break;
}
if (this.elapsed)
{
if (this.Tick != null)
{
this.Tick(this, new EventArgs());
}
}

}
}
public void Stop()
{
this.stopped = true;
}
public event EventHandler Tick;
}
--------------------------------------------------------

按照 jeffery 上个月的课程
“如果你开始考虑线程够不够用 最多能用几个线程 那么你已经走向 very very wrong”的路了






共2页: 1 2 下一页