100165451.htm

来自「C#高级编程(第三版),顶死你们。。 。up」· HTM 代码 · 共 116 行 · 第 1/2 页

HTM
116
字号
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">传送给构造函数的参数必须是这种类型的委托。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">但完成后,新线程实际上并没有执行任务,它只是在等待执行。我们调用</span><span lang="EN-US">Thread.Start()</span><span style="FONT-FAMILY: 宋体">方法来启动线程。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">假定有一个方法</span><span lang="EN-US">ChangeColorDepth()</span><span style="FONT-FAMILY: 宋体">:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">void ChangeColorDepth()</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 13pt; FTEL: 18.45pt"><span lang="EN-US">{</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 13pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; // processing to change color depth of image</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">}</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">执行下述代码:</span></p>
<p class="a6" style="MARGIN-TOP: 8.15pt; BACKGROUND: #f2f2f2; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">Thread depthChangeThread = new Thread();</span></p>
<p class="a6" style="BACKGROUND: #f2f2f2; MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 13pt; FTEL: 18.45pt"><span lang="EN-US">depthChangeThread.Name = &quot;Depth Change Thread&quot;;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 13pt; FTEL: 18.45pt"><span lang="EN-US">ThreadStart entryPoint = new ThreadStart(ChangeColorDepth);</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">depthChangeThread.Start();</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">完成后,两个线程就会同时运行。</span></p>
<p align="center"><span lang="EN-US"><img height="139" src="15/image001.gif" width="227" alt="" /></span></p>
<p style="FTEL: 8.15pt" align="center"><span style="FONT-FAMILY: 宋体">图</span><span lang="EN-US">&nbsp; 15-1</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">在这段代码中,还使用</span><span lang="EN-US">Thread.Name</span><span style="FONT-FAMILY: 宋体">属性给线程赋予一个友好的名称,如图</span><span lang="EN-US">15-1</span><span style="FONT-FAMILY: 宋体">所示,这不是必要的,但非常有效。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">注意,线程的入口</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">在本例中是</span><span lang="EN-US">ChangeColorDepth())</span><span style="FONT-FAMILY: 宋体">不带任何参数,所以必须用其他方式给方法传递它需要的信息。最显而易见的方式就是使用该方法所属的类的成员字段。而且,该方法没有返回值</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">如果有返回值,则应返回到什么地方?只要这个方法返回,运行它的线程就会终止,所以不能接收任何返回值。我们几乎不能把它返回给调用该线程的线程,因为该线程大概在忙着做其他事</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">启动了一个线程后,还可以挂起、恢复或中止它。挂起一个线程就是让它进入睡眠状态,此时,线程仅是停止运行某段时间,不占用任何处理器时间,以后还可以恢复,从被挂起的那个状态重新运行。如果线程被中止,就是停止运行。</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">会永久地删除该线程的所有数据,所以该线程不能重新启动。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">继续上面的图像编辑器例子,假定由于某些原因,用户界面线程显示一个对话框,允许用户选择临时挂起会话进程</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">用户通常不会这么做,但这仅是一个示例,在更真实的示例中,用户可能是暂停声音文件或视频文件的播放</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">。在主线程中编写如下响应:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">depthChangeThread.Suspend();</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">如果用户以后要求恢复该线程,可以使用下面的方法:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">depthChangeThread.Resume();</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">最后,如果用户</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">更真实</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">决定不进行这样的会话,单击取消按钮,可以使用下面的方法:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">depthChangeThread.Abort();</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">注意</span><span lang="EN-US" style="LETTER-SPACING: -0.2pt">Suspend()</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.2pt">和</span> <span lang="EN-US"><span style="LETTER-SPACING: -0.2pt">Abort()</span></span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.2pt">方法不必立即起作用。对于</span><span lang="EN-US" style="LETTER-SPACING: -0.2pt">Suspend()</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.2pt">方法,</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">允许要挂起的线程再执行几个指令,目的是为了到达</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 宋体">认为线程可以安全挂起的状态。这么做,从技术上讲,是为了确保垃圾收集器执行正确的操作,具体内容见</span><span lang="EN-US">MSDN</span><span style="FONT-FAMILY: 宋体">文档说明。在中止线程时,</span><span lang="EN-US" style="LETTER-SPACING: -0.2pt">Abort()</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.2pt">方法会在受影响的线程中产生一个</span><span lang="EN-US" style="LETTER-SPACING: -0.2pt">ThreadAbortException</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.2pt">,</span><span lang="EN-US" style="LETTER-SPACING: -0.2pt">ThreadAbortException</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.2pt">是一个特殊的异常类,以前我们没有遇到过。以这种方式中止线程,如果线程当前执行</span><span lang="EN-US" style="LETTER-SPACING: -0.2pt">try</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.2pt">块中的代码,则在线程真正中止前,将执行相应的</span><span lang="EN-US" style="LETTER-SPACING: -0.2pt">finally</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.2pt">块。这就可以保证清理资源,并有机会确保线程正在处理的数据</span><span lang="EN-US" style="LETTER-SPACING: -0.2pt">(</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.2pt">例如,在线程中止后仍保留的类实例的字段</span><span lang="EN-US" style="LETTER-SPACING: -0.2pt">)</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.2pt">处于有效的状态。</span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>
<p class="a3" style="MARGIN-TOP: 8.15pt; FTEL: 21.45pt"><span style="FONT-FAMILY: 黑体">注意:</span></p>
<p class="a1" style="FTEL: 21.45pt"><span style="FONT-FAMILY: 楷体_GB2312">在开发</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 楷体_GB2312">以前,不推荐使用这种方式中止线程,但极端情况除外,因为受影响的线程会立即中止,它正在处理的数据将处于无效状态,线程所使用的资源仍被占用。</span><span lang="EN-US">.NET</span><span style="FONT-FAMILY: 楷体_GB2312">使用的异常机制可以使线程的中止更加安全。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">这种异常机制可以使线程的中止比较安全,但中止线程要用一定的时间,因为从理论上讲,</span><span lang="EN-US">finally</span><span style="FONT-FAMILY: 宋体">块中的代码执行多长时间是没有限制的。因此,在中止线程后需要等待一段时间,线程被真正中止后,才能继续执行其他操作。如果后续的处理依赖于另一个已经中止的线程,可以调用</span><span lang="EN-US">Join()</span><span style="FONT-FAMILY: 宋体">方法,等待线程中止:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><a ftel="Join1"><span lang="EN-US">depthChangeThread.Abort();</span></a></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">depthChangeThread.Join();</span></p>
<p class="MsoNormal"><span lang="EN-US">Join() </span><span style="FONT-FAMILY: 宋体">的其他重载方法可以指定等待的时间期限。如果过了等待的时间期限,程序会继续执行。如果没有指定时间期限,线程就要等待需要等待的时间。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">上面的代码段还显示了在一个线程上执行操作的另一个线程</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">至少在</span><span lang="EN-US">Join()</span><span style="FONT-FAMILY: 宋体">中,是等待另一个线程</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">。但是,如果主线程要在它自己的线程上执行某些操作,该怎么办?此时需要一个线程对象的引用来表示它自己的线程。使用</span><span lang="EN-US">Thread</span><span style="FONT-FAMILY: 宋体">类的静态属性</span><span lang="EN-US">CurrentThread</span><span style="FONT-FAMILY: 宋体">,就可以获得这样一个引用:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">Thread myOwnThread = Thread.CurrentThread;</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">线程实际上是一个不太好处理的类,因为即使在没有实例化其他线程以前,也总是会有一个线程:目前正在执行的线程。因此处理这个类与其他类有两个区别:</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体">可以实例化一个线程对象,它表示一个正在运行的线程,其实例成员应用于正在运行的线程上。</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体">可以调用任意个静态方法。这些方法一般会应用到实际调用它们的线程上。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">可以调用的一个静态方法是</span><span lang="EN-US">Sleep()</span><span style="FONT-FAMILY: 宋体">,它使正在运行的线程进入睡眠状态,过一段时间之后该线程会继续运行。</span></p></div>
                <!-- page -->
                <div class="page" style="text-align: center">
                    <a href="100165450.htm">上一页</a>&nbsp;&nbsp;&nbsp;<a href="index.html">首页</a>&nbsp;&nbsp;&nbsp;<a href="100165452.htm">下一页</a>
                </div>
                <div style="margin: 0px auto; width: 700px; border: solid 1px #0b5f98;">
                    <div style="float: left; width: 16px; background-color: #0b5f98; color: White; padding: 1px;">
                        图书导读
                    </div>
                    <div style="float: right; width: 670px; text-align: left; line-height: 16pt; padding-left: 2px">
                        <!--导读-->
                        <h1 id="divCurrentNode2" style="color: #b83507; width: 100%; text-align: left; font-size: 12px; padding-left: 2px">当前章节:<a href='100165451.htm'><font color='red'>15.3  线程的处理</font></a></h1>
                        <div id="divRealteNod2" style="padding-left: 2px">
                        <div style='float:left;width:49%'>·<a href='100165448.htm'>14.5  小结</a></div><div style='float:right;width:49%'>·<a href='100165449.htm'>15.1  线程</a></div><div style='float:left;width:49%'>·<a href='100165450.htm'>15.2  多线程应用程序</a></div><div style='float:right;width:49%'>·<a href='100165452.htm'>15.4  ThreadPlayaround示例</a></div><div style='float:left;width:49%'>·<a href='100165453.htm'>15.5  线程的优先级</a></div><div style='float:right;width:49%'>·<a href='100165454.htm'>15.6  同步</a></div></div>
                    </div>
                </div>
                </div>
        </div>
</body>
</html>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?