最近在某处装了一个Whidbey的CTP May版本(应该是May吧?还是March?忘了),因此兴冲冲去玩了一把。稍微熟悉了一下环境,然后就开始试用那些新的功能了。比如说Generics……不过没有我想象当中的兴奋,因为这些东西基本上看过演示和介绍,都知道运行后大概会有什么结果,所以我连运行一下的兴趣都没有。倒是一些从来没有介绍过的功能比较吸引我的注意力,比如说Performance的测试器(相当于Profiler),还有自动生成测试代码。前者的功能有点像以前介绍过的一个Profiler,不过功能甚至没有原来那个强。至于后者,以前听说过,不过没有解图也没有详细的讲解,所以还是挺吸引人的,于是我就迫不及待的想尝试这个功能。用什么来尝试好呢?恩,就用.Game Framework的代码来测一下吧,光测一下DemoCharacter这个类好了。于是右键点击生成测试,结果发现把整个Test目录下面的所有东西都选中了。我想,难道VS2k5这么强,认为一般应该测试整个目录的代码?好吧,那就妥协一下,就测试Test目录下面的吧。点击了Finish还是OK,乖乖,等了半天没见反应,除了CPU几乎全满之外。心想应该在生成代码,确实比较占用资源。那我就去
吧,
完了还没好,再看看报纸吧,报纸全看完了还没有好……-_-b 等了半天终于好了,一看,原来就是自动套用模版生成NUnit的测试代码啊……
我想好像我的那个优化工具似乎也用不了这么长的时间啊,实际上有好几个需要进行代码分析地方速度都会有点慢,是不是代码分析器的分析速度的问题呢?由于速度实在太慢了,而且测试的范围太庞大了,我已经没有心思手动写expected应该是什么的代码了,放弃。可是我还是实在不甘心啊,怎么能不试一下这个功能呢?于是还是想测试一下DemoCharacter这个类,结果发现没有这个类——我忘了abstract的类是不能够测试的,可是如果我非要测试其中一些功能怎么办?百思不得其解,难道非要通过派生类测试?那如果我有一个abstract的BaseX派生出ChildA、ChildB、……、ChildZ,Children.Calc()根据BaseX.Calc()的计算结果来进行不同的计算,那么怎么测试BaseX.Calc()是否正确呢?难道要派生一个BlankChild来测试?那如果这样的问题比较多是不是太不好玩了,也许我的想法太特殊了。
OK,回归正题。原来的.Game Framework的代码在VS2k3的时候好好的,没有warning,跑到Whidbey下面却出现了一大堆的warning。仔细一看,原来说的是Thread.Suspend和Resume已经obsoleted,建议使用Threading下面的其他东西来进行同步,例如Monitor、ManualResetEvent等等来进行线程间的同步。Oops! 这可怎么好?我还是比较讨厌有warning的,先看看这个到底是怎么回事,为什么要废弃这种用法呢?
查了一下Whidbey的MSDN,原来说因为suspend的时候无法控制代码在什么地方被停止,也许正在等待一个SecurityPermission,或者在等待某个资源,或者在……,因此很容易引起死锁。打个比方吧:线程A已经占用了资源1,正在wait资源2,但是资源2被线程B占用了。线程B占用着资源2的同时,也在等待资源1,但是等着等着不耐烦了,他决定做点其他的事情,比如说把线程A挂起来,然后继续等待资源1。本来A等得不耐烦的时候就会释放资源1,可是这样的事情就会被B给彻底阻止了。
但是我的问题似乎还比较不好解决,如果不使用Suspend/Resume的话。因为我正好需要“无论运行到哪里,我都要他暂停”这样的能力。
我的问题是什么一个问题呢:有一个循环需要处理一些任务,但是这个任务必须要能够限制一轮的执行时间在比如50ms内完成,如果不能够完成也必须让位给后面的工作了。
一开始我是打算用Thread.Join(timeout) + Thread.Abort() 的方式来进行的,但是考虑到这样需要不停的产生线程和销毁(甚至终止)线程,开销有点大。此外Abort除了引发Exception占用更多的开销之外,还可能引发不可控制的后果,比如某个资源正在初始化到一半的时候就终止了。因此最终的修改方案是通过AutoResetEvent.WaitOne(timeout) * 2 + Thread.Suspend() + Thread.Resume来完成的。大致的代码如下:
对于这样的一个情况,有没有可能不用suspend呢?需要指出的是,我没有办法控制任何一个call_the_process[i]所可能花费的时间,完全有可能某一个调用需要花费1000ms,因此不太可能在每一次循环的时候检查状态。另外,对于这样的线程间同步的问题(实际上应该说是限制某个循环任务的执行时间的问题),是否有一个比较好的Pattern呢?上面这个是我凭空想出来的,目前工作还算良好。不过到了whidbey下面有warning实在是太难看了,能够有更好的方法解决自然最好,否则怎么说也得要禁止这个warning的显示才行。
诸位有什么好建议呢?


我想好像我的那个优化工具似乎也用不了这么长的时间啊,实际上有好几个需要进行代码分析地方速度都会有点慢,是不是代码分析器的分析速度的问题呢?由于速度实在太慢了,而且测试的范围太庞大了,我已经没有心思手动写expected应该是什么的代码了,放弃。可是我还是实在不甘心啊,怎么能不试一下这个功能呢?于是还是想测试一下DemoCharacter这个类,结果发现没有这个类——我忘了abstract的类是不能够测试的,可是如果我非要测试其中一些功能怎么办?百思不得其解,难道非要通过派生类测试?那如果我有一个abstract的BaseX派生出ChildA、ChildB、……、ChildZ,Children.Calc()根据BaseX.Calc()的计算结果来进行不同的计算,那么怎么测试BaseX.Calc()是否正确呢?难道要派生一个BlankChild来测试?那如果这样的问题比较多是不是太不好玩了,也许我的想法太特殊了。
OK,回归正题。原来的.Game Framework的代码在VS2k3的时候好好的,没有warning,跑到Whidbey下面却出现了一大堆的warning。仔细一看,原来说的是Thread.Suspend和Resume已经obsoleted,建议使用Threading下面的其他东西来进行同步,例如Monitor、ManualResetEvent等等来进行线程间的同步。Oops! 这可怎么好?我还是比较讨厌有warning的,先看看这个到底是怎么回事,为什么要废弃这种用法呢?
查了一下Whidbey的MSDN,原来说因为suspend的时候无法控制代码在什么地方被停止,也许正在等待一个SecurityPermission,或者在等待某个资源,或者在……,因此很容易引起死锁。打个比方吧:线程A已经占用了资源1,正在wait资源2,但是资源2被线程B占用了。线程B占用着资源2的同时,也在等待资源1,但是等着等着不耐烦了,他决定做点其他的事情,比如说把线程A挂起来,然后继续等待资源1。本来A等得不耐烦的时候就会释放资源1,可是这样的事情就会被B给彻底阻止了。
但是我的问题似乎还比较不好解决,如果不使用Suspend/Resume的话。因为我正好需要“无论运行到哪里,我都要他暂停”这样的能力。
我的问题是什么一个问题呢:有一个循环需要处理一些任务,但是这个任务必须要能够限制一轮的执行时间在比如50ms内完成,如果不能够完成也必须让位给后面的工作了。
一开始我是打算用Thread.Join(timeout) + Thread.Abort() 的方式来进行的,但是考虑到这样需要不停的产生线程和销毁(甚至终止)线程,开销有点大。此外Abort除了引发Exception占用更多的开销之外,还可能引发不可控制的后果,比如某个资源正在初始化到一半的时候就终止了。因此最终的修改方案是通过AutoResetEvent.WaitOne(timeout) * 2 + Thread.Suspend() + Thread.Resume来完成的。大致的代码如下:
AutoResetEvent evMain = new ...(false);
AutoResetEvent evLoop = new ...(false);
Thread loopThread = new ...(new ThreadStart(Loop));
// 该函数会被外部的一个大循环不断的调用
void MainLoop()
{
if (loopThread.ThreadState == ThreadState.Unstarted)
{
loopThread.Start(); // 开始循环线程
}
else
{
loopThread.Resume(); // 唤醒上一次被挂起的线程
evLoop.Set(); // 允许进行下一轮的处理(无论上一次是否因为超时被提前暂停)
}
evMain.WaitOne(timeout); // 等待处理,直到完成该轮循环或者超时
loopThread.Suspend(); // 挂起循环线程,无论他是否已经完成当前的处理了。
}
// 需要限制时间的任务
void Loop()
{
for (i = 0; i < c; i++)
{
call_the_process[i](); // 外部的、可能是其他人写的代码。
}
evMain.Set(); // 当前循环已经完成,允许主线程继续下面的代码。
evLoop.WaitOne(); // 等待下一次循环的机会
}
对于这样的一个情况,有没有可能不用suspend呢?需要指出的是,我没有办法控制任何一个call_the_process[i]所可能花费的时间,完全有可能某一个调用需要花费1000ms,因此不太可能在每一次循环的时候检查状态。另外,对于这样的线程间同步的问题(实际上应该说是限制某个循环任务的执行时间的问题),是否有一个比较好的Pattern呢?上面这个是我凭空想出来的,目前工作还算良好。不过到了whidbey下面有warning实在是太难看了,能够有更好的方法解决自然最好,否则怎么说也得要禁止这个warning的显示才行。
诸位有什么好建议呢?
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?