<?xml version="1.0" encoding="gb2312"?>
<rss version="2.0">
<channel>
<title><![CDATA[六子的博客_Blog]]></title>
        <image>
        <title>http://hi.baidu.com</title>
        <link>http://hi.baidu.com</link>
        <url>http://img.baidu.com/img/logo-hi.gif</url>
        </image>
<description><![CDATA[积极学习.NET!]]></description>
<link>http://hi.baidu.com/zck98530</link>
<language>zh-cn</language>
<generator>www.baidu.com</generator>
<ttl>5</ttl>


<item>
        <title><![CDATA[[转]深度解析Asp.Net2.0中的Callback机制]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/5e327a318c983913eac4afae.html]]></link>
        <description><![CDATA[
		
		<p>我们都知道，凡是AJAX，从底层来讲，无外乎两种实现机制：XMLHTTP以及IFRAME。在AJAX这个词获得广泛关注之前，其实，基于这两种底层实现的功能框架，或者基于这两种技术的无刷新效果实现就已经被广泛的使用了。当然，发展到今天，在使用接口方面，这些底层机制的细节往往被框架给隐藏了，使用接口变得越来越简单，用户只要调用这些简单接口，没有必要知道具体是怎么实现效果的了。</p>
<p>不过，这里我们既然是要解析callback的实现机制，那还是让我们从一个callback调用的客户端脚本调用开始，看看，微软是怎么实现这个callback机制的。</p>
<p>1、ClientScript.GetCallbackEventReference(...)</p>
<p>要激发一个callback，首先，当然需要在客户端本中发出一个调用。一个典型的调用语法如下：</p>
<p>&lt;script language=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt; <br>
function any_script_function(arg, context) <br>
{ <br>
&nbsp;&nbsp;&nbsp;  &lt;%= ClientScript.GetCallbackEventReference(this, &quot;arg&quot;, &quot;ReceiveServerData&quot;, &quot;context&quot;)%&gt;;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
} <br>
&lt;/script&gt; <br>
ClientScript.GetCallbackEventReference(...)将根据传入的参数返回实际的回调脚本。这个函数有多个重载版本，因此，这些参数的含义，大家可以参考MSDN。以具体的上面这段示例代码中的参数来说：</p>
<p>- this表示执行回调的的服务端控件是当前这个Page，当前的Page必须实现ICallbackEventHandler接口，包括必须实现string GetCallbackResult()和void RaiseCallbackEvent(eventArgument)这两个接口函数，这个参数也可以是指向某个WEB控件的引用，当然，这个空间也必须实现ICallbackEventHandler接口；</p>
<p>- &quot;arg&quot;是将被传给RaiseCallbackEvent的参数eventArgument的值，可以使人以自定义格式的字符串；</p>
<p>- &quot;ReceiveServerData&quot;是当回调成功之后，处理返回内容的客户端脚本函数的名称，这个函数必须存在于执行回调的页面，并且这个函数可以包含两个参数，例如：</p>
<p>&lt;script type=&quot;text/javascript&quot;&gt;  <br>
&nbsp;&nbsp;&nbsp;  function ReceiveServerData(result, context)  <br>
&nbsp;&nbsp;&nbsp;  {  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  }  <br>
&lt;/script&gt; <br>
这两个参数，分别是回调的返回数据result，和原封不动被返回的我们激发回调时的这个context参数，当然，这两个参数都是字符串类型的。</p>
<p>- &quot;context&quot;就不用多解释了，记得这个参数会被原封不动的传给指定的返回数据处理函数就行了。MSDN的官方文档说，context一般可用来传递需要在客户端的返回数据处理函数中用来调用的脚本代码，不过实际上，你传什么都可以，把它看成一种从客户端回调的的激发端，到处理返回数据的接收段之间的参数传递通道就行了。</p>
<p>2、WebForm_DoCallback(...)</p>
<p>Ok，明白了以上代码的含义，下面我们来看看，前面的这条&ldquo;&lt;%= ClientScript.GetCallbackEventReference(this, &quot;arg&quot;, &quot;ReceiveServerData&quot;, &quot;context&quot;)%&gt;;&rdquo;在运行时会被解析成什么样子呢？我们只要在页面运行时察看页面源码就可以看到，实际上服务器帮我们生成了下面这段script代码：</p>
<p>&lt;script language=&quot;javascript&quot; type=&quot;text/javascript&quot;&gt; <br>
function any_script_function() <br>
{ <br>
&nbsp;&nbsp;&nbsp;  WebForm_DoCallback('__Page',arg,ReceiveServerData,context,null,false);&nbsp;&nbsp;&nbsp;&nbsp;  <br>
} <br>
&lt;/script&gt; <br>
这段代码是什么意思呢？很显然的他调用了一个系统与定义的script函数：WebForm_DoCallback。我们要把这个函数找出来看看它具体为我们干了什么。在运行时的页面源码中，我们很容易可以找到这段脚本的出处。我们注意到有一个script，src=&quot;/TestCallbackWeb/WebResource.axd?d=HEcYmh-7_szSIu1D_mHSEw2&amp;amp;t=632661779991718750&quot;，这里就定义了WebForm_DoCallback。让我们把它用flashget下载下来，将扩展名改为.js。看看源码吧，没有被混淆的，所以很容易看明白。我这里就只把和callback相关的部分贴出来解释一下，见代码中的注释：</p>
<p>//用于存放所有未完成的callback对象的数组__pendingCallbacks<br>
var __pendingCallbacks = new Array();<br>
var __synchronousCallBackIndex = -1;</p>
<p>//回调主函数WebForm_DoCallback<br>
function WebForm_DoCallback(eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync) {</p>
<p>&nbsp;&nbsp;&nbsp;  //构造回调参数，回调参数包括了原来页面上的formpostdata和我们传递的目标控件、eventArgument和部分验证信息<br>
&nbsp;&nbsp;&nbsp;  var postData = __theFormPostData +<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &quot;__CALLBACKID=&quot; + WebForm_EncodeCallback(eventTarget) +<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &quot;&amp;__CALLBACKPARAM=&quot; + WebForm_EncodeCallback(eventArgument);<br>
&nbsp;&nbsp;&nbsp;  if (theForm[&quot;__EVENTVALIDATION&quot;]) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  postData += &quot;&amp;__EVENTVALIDATION=&quot; + WebForm_EncodeCallback(theForm[&quot;__EVENTVALIDATION&quot;].value);<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  <br>
&nbsp;&nbsp;  //下面实例化XMLHTTP对象，如果浏览器支持XMLHTTP则直接用XMLHTTP执行异步回调<br>
&nbsp;&nbsp;&nbsp;  var xmlRequest,e;<br>
&nbsp;&nbsp;&nbsp;  try {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequest = new XMLHttpRequest();<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  catch(e) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  try {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequest = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  catch(e) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  var setRequestHeaderMethodExists = true;<br>
&nbsp;&nbsp;&nbsp;  try {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  setRequestHeaderMethodExists = (xmlRequest &amp;&amp; xmlRequest.setRequestHeader);<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  catch(e) {}<br>
&nbsp;&nbsp;&nbsp;  var callback = new Object();<br>
&nbsp;&nbsp;&nbsp;  callback.eventCallback = eventCallback;<br>
&nbsp;&nbsp;&nbsp;  callback.context = context;<br>
&nbsp;&nbsp;&nbsp;  callback.errorCallback = errorCallback;<br>
&nbsp;&nbsp;&nbsp;  callback.async = useAsync;<br>
&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;  //获取对应的回调对象 <br>
&nbsp;&nbsp;&nbsp;  var callbackIndex = WebForm_FillFirstAvailableSlot(__pendingCallbacks, callback);<br>
&nbsp;&nbsp;&nbsp;  if (!useAsync) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (__synchronousCallBackIndex != -1) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  __pendingCallbacks[__synchronousCallBackIndex] = null;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  __synchronousCallBackIndex = callbackIndex;<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  if (setRequestHeaderMethodExists) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequest.onreadystatechange = WebForm_CallbackComplete;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callback.xmlRequest = xmlRequest;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequest.open(&quot;POST&quot;, theForm.action, true);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequest.setRequestHeader(&quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequest.send(postData);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  return;<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  <br>
&nbsp;&nbsp;  //万一浏览器不支持XMLHTTP的话，我们IFRAME方案代替，在一个隐藏的IFRAME中执行Postback&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  callback.xmlRequest = new Object();<br>
&nbsp;&nbsp;&nbsp;  var callbackFrameID = &quot;__CALLBACKFRAME&quot; + callbackIndex;<br>
&nbsp;&nbsp;&nbsp;  var xmlRequestFrame = document.frames[callbackFrameID];<br>
&nbsp;&nbsp;&nbsp;  if (!xmlRequestFrame) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame = document.createElement(&quot;IFRAME&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.width = &quot;1&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.height = &quot;1&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.frameBorder = &quot;0&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.id = callbackFrameID;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.name = callbackFrameID;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.style.position = &quot;absolute&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.style.top = &quot;-100px&quot;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.style.left = &quot;-100px&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  try {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (callBackFrameUrl) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.src = callBackFrameUrl;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  catch(e) {}<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  document.body.appendChild(xmlRequestFrame);<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  var interval = window.setInterval(function() {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame = document.frames[callbackFrameID];<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (xmlRequestFrame &amp;&amp; xmlRequestFrame.document) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  window.clearInterval(interval);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.document.write(&quot;&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.document.close();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.document.write('&lt;html&gt;&lt;body&gt;&lt;form method=&quot;post&quot;&gt;&lt;input type=&quot;hidden&quot; name=&quot;__CALLBACKLOADSCRIPT&quot; value=&quot;t&quot;&gt;&lt;/form&gt;&lt;/body&gt;&lt;/html&gt;');<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.document.close();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.document.forms[0].action = theForm.action;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var count = __theFormPostCollection.length;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var element;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (var i = 0; i &lt; count; i++) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  element = __theFormPostCollection[i];<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (element) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var fieldElement = xmlRequestFrame.document.createElement(&quot;INPUT&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  fieldElement.type = &quot;hidden&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  fieldElement.name = element.name;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  fieldElement.value = element.value;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.document.forms[0].appendChild(fieldElement);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var callbackIdFieldElement = xmlRequestFrame.document.createElement(&quot;INPUT&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackIdFieldElement.type = &quot;hidden&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackIdFieldElement.name = &quot;__CALLBACKID&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackIdFieldElement.value = eventTarget;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.document.forms[0].appendChild(callbackIdFieldElement);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var callbackParamFieldElement = xmlRequestFrame.document.createElement(&quot;INPUT&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackParamFieldElement.type = &quot;hidden&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackParamFieldElement.name = &quot;__CALLBACKPARAM&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackParamFieldElement.value = eventArgument;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.document.forms[0].appendChild(callbackParamFieldElement);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (theForm[&quot;__EVENTVALIDATION&quot;]) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var callbackValidationFieldElement = xmlRequestFrame.document.createElement(&quot;INPUT&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackValidationFieldElement.type = &quot;hidden&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackValidationFieldElement.name = &quot;__EVENTVALIDATION&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackValidationFieldElement.value = theForm[&quot;__EVENTVALIDATION&quot;].value;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.document.forms[0].appendChild(callbackValidationFieldElement);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var callbackIndexFieldElement = xmlRequestFrame.document.createElement(&quot;INPUT&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackIndexFieldElement.type = &quot;hidden&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackIndexFieldElement.name = &quot;__CALLBACKINDEX&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackIndexFieldElement.value = callbackIndex;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.document.forms[0].appendChild(callbackIndexFieldElement);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.document.forms[0].submit();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  }, 10);<br>
}</p>
<p>//该函数在每次回调结束后会调用来检查当前的回调列表中的回调的执行情况，如果，执行完毕的，则从列表中删除回调对象，并删除临时建立的IFRAME<br>
function WebForm_CallbackComplete() {<br>
&nbsp;&nbsp;&nbsp;  for (i = 0; i &lt; __pendingCallbacks.length; i++) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackObject = __pendingCallbacks[i];<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (callbackObject &amp;&amp; callbackObject.xmlRequest &amp;&amp; (callbackObject.xmlRequest.readyState == 4)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  WebForm_ExecuteCallback(callbackObject);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (!__pendingCallbacks[i].async) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  __synchronousCallBackIndex = -1;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  __pendingCallbacks[i] = null;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var callbackFrameID = &quot;__CALLBACKFRAME&quot; + i;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var xmlRequestFrame = document.getElementById(callbackFrameID);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (xmlRequestFrame) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  xmlRequestFrame.parentNode.removeChild(xmlRequestFrame);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  }<br>
}</p>
<p>//该函数执行我们在回调激发端指定的处理返回数据的script函数，如我们上面范例代码中的ReceiveServerData函数<br>
function WebForm_ExecuteCallback(callbackObject) {<br>
&nbsp;&nbsp;&nbsp;  var response = callbackObject.xmlRequest.responseText;<br>
&nbsp;&nbsp;&nbsp;  if (response.charAt(0) == &quot;s&quot;) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if ((typeof(callbackObject.eventCallback) != &quot;undefined&quot;) &amp;&amp; (callbackObject.eventCallback != null)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackObject.eventCallback(response.substring(1), callbackObject.context);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  else if (response.charAt(0) == &quot;e&quot;) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if ((typeof(callbackObject.errorCallback) != &quot;undefined&quot;) &amp;&amp; (callbackObject.errorCallback != null)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackObject.errorCallback(response.substring(1), callbackObject.context);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  else {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var separatorIndex = response.indexOf(&quot;|&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (separatorIndex != -1) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var validationFieldLength = parseInt(response.substring(0, separatorIndex));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (!isNaN(validationFieldLength)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var validationField = response.substring(separatorIndex + 1, separatorIndex + validationFieldLength + 1);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (validationField != &quot;&quot;) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var validationFieldElement = theForm[&quot;__EVENTVALIDATION&quot;];<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (!validationFieldElement) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  validationFieldElement = document.createElement(&quot;INPUT&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  validationFieldElement.type = &quot;hidden&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  validationFieldElement.name = &quot;__EVENTVALIDATION&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  theForm.appendChild(validationFieldElement);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  validationFieldElement.value = validationField;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if ((typeof(callbackObject.eventCallback) != &quot;undefined&quot;) &amp;&amp; (callbackObject.eventCallback != null)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  callbackObject.eventCallback(response.substring(separatorIndex + validationFieldLength + 1), callbackObject.context);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  }<br>
}</p>
<p>//获取对应的回调对象 <br>
function WebForm_FillFirstAvailableSlot(array, element) {<br>
&nbsp;&nbsp;&nbsp;  var i;<br>
&nbsp;&nbsp;&nbsp;  for (i = 0; i &lt; array.length; i++) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (!array[i]) break;<br>
&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  array[i] = element;<br>
&nbsp;&nbsp;&nbsp;  return i;<br>
}</p>
<p>//再下面是一些辅助函数和与callback关系不大的函数，我就不列出来了，有兴趣的朋友可以自己看看<br>
//<br>
从以上代码我们可以很明白的看到，系统判断您的浏览器是否支持XMLHTTP或IFRAME，如果至少支持其中之一，则用相应的方法执行回调，否则当然就是提示错误了。回调的时候，采用post的方式，异步post到当前页面，然后等待回调结束，此时，由我们指定的返回数据处理script函数来处理返回的数据。</p>
<p>看到这里，我还不知道服务端怎么处理这个根据传过来的参数解析、执行，并返回数据的过程。但是，我们已经知道，WebForm_DoCallback(...)将会将当前页面的web控件的信息都post回去，这就意味着，我们在服务端有可能可以访问到这些web控件的value，这还不错，方便了我们处理当前数据。另一方面，eventArgument既然是一个任意格式的字符串参数，我们肯定要在服务段自己解析它的。</p>
<p>Serverside Callback Operation &amp; Render</p>
<p>好了，那么接下来就让我们来看看在服务端，ASP.NET都为我们做了些什么。</p>
<p>首先，我们知道，当前的Page是必须实现ICallbackEventHandler这个接口的，也就是其包含的两个函数：string GetCallbackResult()和void RaiseCallbackEvent(eventArgument)。根据MSDN的文档，我们知道，在一个callback被post到服务端时，Page将会首先将post回来的form data绑定到当前页面的服务端web控件，接着判断本次post是callback还是postback，如果是postpost，那么自然是原来的那个机制；</p>
<p>如果是callback，则将回调用触发本次callback的控件（在本例中，我们在激发这个callback时，第一个参数指定的是this也就是当前的Page，那么这里当前的Page就是这个触发控件）的RaiseCallbackEvent(eventArgument)，当然，eventArgument也将会正确的传过来，在这个函数的实现代码里我们可以对这个参数进行解析处理，并在某个地方，存储我们准备返回的数据，或者待处理的已经被解析出来的参数；</p>
<p>接着，系统将调用string GetCallbackResult()，在这个函数的实现代码中，我们可以直接返回我们在RaiseCallback函数中存储的准备返回的数据，或者根据待处理的已经被解析出来的参数处理这些参数，并返回结果。这个返回的字符串，自然将以脚本的形式被render回客户端。被返回的脚本细节如下(反编译Page.RenderCallback()的源码)，我们可以看到，返回的结果除了我们需要的结果数据和相应的脚本，没有多余的数据，因此，callback的执行效率应该说还是不错的：</p>
<p>private void RenderCallback()<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  bool flag1 = !string.IsNullOrEmpty(this._requestValueCollection[&quot;__CALLBACKLOADSCRIPT&quot;]);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  try<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  string text1 = null;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (flag1)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  text1 = this._requestValueCollection[&quot;__CALLBACKINDEX&quot;];<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (string.IsNullOrEmpty(text1))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  throw new HttpException(SR.GetString(&quot;Page_CallBackInvalid&quot;));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (int num1 = 0; num1 &lt; text1.Length; num1++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (!char.IsDigit(text1, num1))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  throw new HttpException(SR.GetString(&quot;Page_CallBackInvalid&quot;));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write(&quot;&lt;script&gt;parent.__pendingCallbacks[&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write(text1);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write(&quot;].xmlRequest.responseText=\&quot;&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (this._callbackControl != null)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  string text2 = this._callbackControl.GetCallbackResult();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (this.EnableEventValidation)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  string text3 = this.ClientScript.GetEventValidationFieldValue();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write(text3.Length.ToString(CultureInfo.InvariantCulture));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write('|');<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write(text3);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  else<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write('s');<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write(flag1 ? Util.QuoteJScriptString(text2) : text2);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (flag1)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write(&quot;\&quot;;parent.__pendingCallbacks[&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write(text1);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write(&quot;].xmlRequest.readyState=4;parent.WebForm_CallbackComplete();&lt;/script&gt;&quot;);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  catch (Exception exception1)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Clear();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write('e');<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (this.Context.IsCustomErrorEnabled)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write(SR.GetString(&quot;Page_CallBackError&quot;));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  return;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.Response.Write(flag1 ? Util.QuoteJScriptString(HttpUtility.HtmlEncode(exception1.Message)) : HttpUtility.HtmlEncode(exception1.Message));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
}<br>
另外，才发现原来System.Web.UI.Utils这个类中有那么多有用的方便的函数如QuateJScriptString()，以前一直自己手写这样功能的函数呢~~真傻呀~~</p>
<p>Conclusion</p>
<p>至此，我们已经基本上清楚明白callback的前台幕后了。如果您对服务段的处理过程的细节还觉得不够，您也可以自行反编译Page对象，看看其实现代码的细节，还是很有意思的。</p>
<p>总体而言，我们发现，callback无论是兼容性（XMLHTTP或IFRAME我想大多数浏览器都支持吧），还是性能（没有返回不需要的数据），还是使用的便利性（因为ASP.NET帮我们绑定了页面上的当前的Web控件的数据，这就意味着我们可以在callback后的服务端，象postback时一样来写代码，也方便我们移植原来的postback的代码到callback方式的代码）都是非常优秀的。我们也完全可以扩展现有的控件，或者写我们自己的控件以支持这样的callback效果，并且，混合使用callback控件和原来的postback方式的控件也是非常可靠和容易的。这对我们升级原来的基于postback为主的代码，是非常有利的，如果用Atlas来做同样的代码升级和与postback方式的控件混合使用，我可以跟您说，会有很多问题。不信你自己可以试试~~</p>
<p> </p>
<p>本文来自CSDN博客，出处：<a href="http://blog.csdn.net/lyangsha/archive/2006/12/09/1435820.aspx">http://blog.csdn.net/lyangsha/archive/2006/12/09/1435820.aspx</a></p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/asp%2Enet">asp.net</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/5e327a318c983913eac4afae.html#comment">查看评论</a>]]></description>
        <pubDate>2009年11月02日 星期一  14:06</pubDate>
        <category><![CDATA[asp.net]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/5e327a318c983913eac4afae.html</guid>
</item>

<item>
        <title><![CDATA[[转]服务器端控件三种ID：ID,ClientID和UniqueID]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/8901f4361d93253b0b55a929.html]]></link>
        <description><![CDATA[
		
		<p>在ASP.NET 的服务器端控件中有三种关于 ID 的属性，即 ID, ClientID 和 UniqueID。</p>
<p>ID 表示控件的服务器端编程的标识符，我们写&quot;服务器端的代码&quot;，就要用到这个 ID, 通过这个 ID 可以在服务器端对服务器端控件的属性、方法和时间进行编程访问。（可写）</p>
<p>ClientID 表示由服务器端生成的客户端控件的ID,&quot;经常用于在客户端脚本中访问服务器控件所呈现的 HTML 元素&quot;。一般情况下与服务器端的 ID 相同，有时，不能为控件生成唯一的名称，例如，如果Repeater 空间在它的某个模板中包含一个 Label 控件，则将在客户端生成多个该 Lable 的 HTML 元素, 为防止命名冲突，ASP.NET 为各个服务器控件生成一个唯一的 ClientID ,ClientID 通过将子控件的父控件的 UniqueID 值与控件的 ID 值连接生成，各个部分之间以下划线 _ 连接。（只读）</p>
<p>UniqueID 用于获取服务器控件的唯一的、以分层方式表示的标识符。当将控件放置到重复控件（Repeater、DataList和DataGrid）中时，将可能生成多个服务器端的控件，这就需要区分服务器端的各个控件，以使它们的 ID 属性不冲突。UniqueID 通过将子控件的父控件的 UniqueID 值与控件的 ID 值连接生成，各个部分之间以IdSeparator 属性指定的字符连接。默认情况下， IdSeparator 属性为冒号字符 (:)。此属性为在 .Net Framework2.0种新增加。js与aps.net交互一般情况下使用&lt;%=控件ID.ClientID%&gt;就OK了,但如果用到母版页(MasterPage)则要使用UniqueID获得获值。（只读）</p>
<p> </p>
<p><br>
例如，创建以下 ASP.NET 服务器控件：</p>
<p> &lt;asp:textbox id=&quot;TextBox1&quot; runat=&quot;server&quot; text=&quot;Sample Text&quot; /&gt;</p>
<p>ClientID 属性被设置为 TextBox1，在基于 HTML 的浏览器中，其结果元素与以下所示类似：</p>
<p> &lt;input name=&quot;TextBox1&quot; type=&quot;text&quot; value=&quot;Sample Text&quot; id=&quot;Text1&quot; /&gt;</p>
<p> </p>
<p>可以使用这些属性在客户端脚本中引用服务器控件。通常，必须在客户端脚本中用完全限定引用来引用控件；如果控件是页面中 form 元素的子控件，则一般使用document.forms[0].TextBox1.value = &quot;New value&quot;在客户端脚本中引用控件。</p>
<p>有些控件将子控件呈现在页面中。这些控件中包括数据列表控件（如GridView、DetailsView、FormView、DataList 和 Repeater 控件）、用户控件和 Web 部件控件。可以看到，在这些情况下，子控件可能不具有唯一的 ID，这可能是因为子控件是在某个模板中定义的，该模板会为每个数据行（数据列表控件）生成新的控件实例，也可能是因为可以从外部源（用户控件和 Web 部件控件）将父控件添加到页面中对于每个子控件：控件的 UniqueID 被呈现为 name。控件的 ClientID 被呈现为 id 属性。</p>
<p>ClientID 和 UniqueID 属性都基于原始的 ID 属性，并用足够的信息进行了修改，以保证页面中结果的唯一性。ClientID的值可在客户端脚本中引用。如果在浏览器中显示一个具有命名容器的页面，则可以查看该页面的源文件，从中找到唯一的 ID，这些 ID 作为命名容器子控件的 name 属性和 id 属性生成。但是，建议不要依赖于直接引用在浏览器中看到的 ID。因为用于生成子控件唯一ID 的公式可能会发生变化，应当获取子控件的 ClientID 属性值，并用该值来引用该子控件。例如，您可能会在页面中动态创建客户端脚本。如果客户端脚本引用一个子控件，则应获取该子控件的 ClientID 属性，并将其嵌入到动态脚本中。</p>
<p>例2：</p>
<p> </p>
<p>假设有子控件：</p>
<p>&lt;asp:TextBox ID = &quot;textboxInfo&quot; runat =&quot;server&quot; Text = &quot;Test Text box&quot; name=&quot;haha&quot;&gt;&lt;/asp:TextBox&gt;</p>
<p>那么我们可以在脚本中这样写</p>
<p>var tempt = '&lt;%=textboxInfo.ClientID%&gt;';</p>
<p>var controlname = document.getElementById(tempt).name;</p>
<p>var controlid = document.getElementById(tempt).id;</p>
<p>　　还有一个问题我们需要注意：在使用UniqueID和ClientID的时候要小心点，千万不要&ldquo;迫不及待&rdquo;地使用了这些属性，在运行的过程中可能会碰到一些让人头疼的问题.</p>
<p> </p>
<p><br>
注意 <br>
除了用来分隔 ID 值的是下划线字符而不是 IdSeparator 属性指定的字符以外，为控件生成的 ClientID 值与 UniqueID 值相同。默认情况下，IdSeparator 属性设置为冒号字符 (:)。由于 ClientID 值不包含冒号字符，因此，它可以用于不支持包含冒号的 ID 的 ECMAScript。ClientID 值经常用于以编程方式访问为客户端脚本中的控件呈现的 HTML 元素。有关详细信息，请参见 ASP.NET 网页中的客户端脚本。</p>
<p>总结：<br>
ID，用于server端编程引用控件，没有对应的client值，即不呈现到html中。</p>
<p>UniqueID，<br>
asp.net引擎按控件树层次生成的分层形式限定的标志符，连接符默认为 $ （美元符号）【注：MSDN说默认为 : （冒号），实际是 $ ，可能文档有误吧】，此连接符在asp.net 2.0 中由属性 IdSeparator 指定，在client中呈现为html元素的name属性<br>
此属性主要用来提交（PostBack）客户端数据，如Request.Form[someControl.UnqiueID]</p>
<p>ClientID，<br>
由父控件的UnqiueID连接本身ID而成，但是连接符不一样，默认为&nbsp;&nbsp;  _ （下划线），此连接符在asp.net 2.0 中由属性 ClientIDSeparator 指定，在client中呈现为html元素的id属性，此属性主要在客户端教本中使用，如 var o = document.getElementById('&lt;% = someControl.ClientID %&gt;');</p>
<p>关于 UniqueID的层次分隔符号，1.x 中为 :（冒号），而 2.0 已实现为 $（美元符），主要原因可能是 javascript 中标识符是允许 $，而不允许 : 的。（当你偷懒的时候，可以在 js 中直接使用表单元素的 name属性应用该表单元素，而不用 document.getElementsByName 或者 document.getElementById，不推荐:)</p>
<p><br>
ASP.NET 使用的回发机制（简单版本）是通过一个原型为 __doPostBack(&lt;ControlUniqueID&gt;, &lt;CommandArgs&gt;) 的 javascript 函数</p>
<p>function __doPostBack(eventTarget, eventArgument) {<br>
&nbsp;&nbsp;&nbsp;  if (!theForm.onsubmit || (theForm.onsubmit() != false)) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  theForm.__EVENTTARGET.value = eventTarget;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  theForm.__EVENTARGUMENT.value = eventArgument;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  theForm.submit();<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
}<br>
 此函数的第一个参数 &lt;ControlUniqueID&gt; 对应引起页面回发控件的客户端 name 属性/服务端 UniqueID 属性，当用户引发一个事件，如点击按钮，选择列表框的某一项，首先通过 _doPostBack 函数将此值存在隐藏域中，然后提交页面。<br>
 在服务器端，ASP.NET 引擎通过 HttpRequest.HttpMethod 确定请求是否为 post 方式，若是，则检索HttpRequest.Request.Form[&quot;__EVENTTARGET']， 获取引发回发的控件唯一标识符，并在页面控件集合层次中查找，若找到此控件，则将在适当阶段引发服务器端事件。</p>
<p>另补充控件变化规律如下:</p>
<p>控件名字发生变化是因为 INamingContainer这个接口。这个接口没有任何方法，仅只作为一个标记。ASP.NET维护控件name和id生成的规律是:NamingContainer爷爷$NamingContainer爸爸$该控件的ID。id则一般将$换为&quot;_&quot;。<br>
 你把控件直接放到form下，它头顶唯一一个NamingContainer是Page，但是这个是特殊的逻辑，不会生成__Page_控件名，所以就只剩控件名了，于是ID看起来没有变化。<br>
 当你把控件放到Repeater中时，Repeater自己被INamingContainer标记，同时，每一次循环，它会把模板内的控件重新生成一遍，同时生成一个RepeaterItem， 把这些根据模板生成的控件加入RepeaterItem的子控件。这个RepeaterItem也是一个NamingContainer. 于是控件中就会带有:<br>
RepeaterID(Data)_RepeaterItemID(ctl + 号码)_控件ID.</p>
<p>不过非runat=server控件因为不由ASP.NET维护, 不会发生变化. UserControl.ascx由于其基类也是一个NamingContainer, 所以如果你把控件放入.ascx, 然后在页面上引用, 则前面又会多一层UserControl的ID.</p>
<p>通过controls集合访问服务器控件：</p>
<p>在VS2005中新建一个.aspx文件，打开HTML页会发现一个原先的声明从 <br>
 &lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0 Transitional//EN&quot; &gt; <br>
变成了 <br>
 &lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot;  &quot;<a href="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd</a>&quot;&gt;! <br>
很早以前就称的HTML的接班人XHTML，现在MS终于要将它扶正了.. <br>
这样在写HTML代码时就要注意了, <br>
如: <br>
&lt;font&gt; <br>
&nbsp;&nbsp;&nbsp;  &lt;div&gt; <br>
&nbsp;&nbsp;&nbsp;  &lt;/font&gt; <br>
&nbsp;&nbsp;&nbsp;  &lt;/div&gt; <br>
是无法在Vs2005中的Design模式中正确显示的[很明显的错误，但在HTML可以正常显示].. ,XHTML的语法比HTML严格的</p>
<p>多 <br>
而关于XHTML和HTML的区别，如果不是非常明白<a href="http://www.blueidea.com/tech/site/2004/1911.asp">http://www.blueidea.com/tech/site/2004/1911.asp</a>这个文章可以参考一下。</p>
<p>Form</p>
<p>Form新添加了几个功能比较有用的是defaultbutton、defaultfocus。从字面的意思大家就可以理解了以前在ASP.NET中让人头痛的默认提交表单按钮和设置焦点在ASP.NET 2.0已经提供了，不用象以前那样自己写javascript来控制了</p>
<p>关于焦点在也可以代码中通过 this.SetFocus()来设置了,看得出来ASP.NET2.0是设计是多么的细致。</p>
<p>Header <br>
在代码中可能通过 <br>
 this.Header.Metadata.Add(&quot;taye&quot;, &quot;value&quot;); <br>
 this.Header.Title = &quot;value&quot;; <br>
 this.Header.LinkedStyleSheets.Add(&quot;style.css&quot;); <br>
来控制Title,Meta,Style等[好象LinkedStyleSheets只能是text/css???] <br>
 this.Header.StyleSheet.RegisterStyle()<br>
方法将一个style内嵌到网页中去.</p>
<p>这样页面几乎所以部分都可以得到控制了</p>
<p>有些人也许会想那&lt;html&gt;和&lt;body&gt;呢 <br>
我们先来运行一下面这个代码.</p>
<p>&nbsp;&nbsp;  private void Page_Load(object sender, EventArgs e) <br>
&nbsp;&nbsp;&nbsp;  { <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  foreach (Control ctl in Page.Controls) <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  { <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Response.Write(ctl.ToString() + &quot;&lt;BR/&gt;&quot;);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  LiteralControl lc = ctl as LiteralControl;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (lc != null) <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  { <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Response.Write(lc.Text); <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  } <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }</p>
<p>&nbsp;&nbsp;&nbsp;  }</p>
<p><br>
你将会看到一个正常页的有如下五个控件 <br>
System.Web.UI.LiteralControl <br>
System.Web.UI.HtmlControls.HtmlHead <br>
System.Web.UI.LiteralControl <br>
System.Web.UI.HtmlControls.HtmlForm <br>
System.Web.UI.LiteralControl</p>
<p>而三个LiteralControl的控件的内容分别为</p>
<p>System.Web.UI.LiteralControl <br>
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot; &quot;<a href="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd</a>&quot;&gt;</p>
<p>&lt;html xmlns=&quot;<a href="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>&quot; &gt;</p>
<p>System.Web.UI.LiteralControl <br>
&lt;body&gt; <br>
&nbsp;&nbsp;&nbsp;&nbsp;  <br>
System.Web.UI.LiteralControl <br>
&lt;/body&gt; <br>
&lt;/html&gt;</p>
<p>所以如果你要对body或&lt;!DOCTYPE..&gt;或&lt;html&gt;进行控制那你就找到这相应的控件以后再进行相应的修改吧。只要对</p>
<p>LiteralControl.Text进行修改就可以.</p>
<p><br>
 </p>
<p>--------------------------------------------------------------------------</p>
<p> </p>
<p>从外部的js文件中获取ASPX页面的控件ClientID</p>
<p> </p>
<p> </p>
<p>前言</p>
<p>当使用MasterPage、UserControl等容器时，为了避免控件的重复命名，asp.net会自动将容器中的控件生成一个ClientID（Control Tree中的可生成，否则不会生成）。</p>
<p>例如：ContentPlaceHolder1中的Button1默认情况下会生&ldquo;ctl00_ContentPlaceHolder1_Button1&rdquo;的ClientID。我们在Render出来的mark up中看到的也是这些ClientID。所以，当我们使用JavaScript对控件元素进行操作的时候，必须使用ClientID来对控件进行查找。</p>
<p> </p>
<p>Inline情况下的解决方案</p>
<p>如果JavaScript代码写在.aspx文件中时，也就是Inline Script时。在页面生成的时候，我们能够通过绑定机制将控件的ClientID绑定到页面Mark up中，故可使用：</p>
<p> --&gt;document.getElementById(&quot;&lt;%=Me.txtTest.ClientID %&gt;&quot; ) <br>
来获取一个控件的真实引用，当然，FindControl等方法也可以写在&lt;%=...%&gt;中用来绑定服务端数据到客户端。</p>
<p> </p>
<p>external JS情况下的解决方案</p>
<p>然而，部分情况下，为了解耦，我们常常把JavaScript单独写在.js文件中，再引用到aspx文件中去。这种情况下，.js文件内的代码不能通过&lt;%=...%&gt;来进行服务端数据的绑定，所以上面的方法是不能用的。</p>
<p>此时简单点的解决方案就是直接在JavaScript中写控件的ClientID，但这样增加了JS文件和ASPX的耦合度，非常不推荐使用。</p>
<p>我常用的方法有两种，在此抛砖引玉：</p>
<p> </p>
<p>案例：</p>
<p>Default5.aspx是MasterPage.master 的内容页，本例中的主要文件。</p>
<p>JScript.js是一个外部的js文件，用来处理JavaScript操作。</p>
<p>Button1是Default5.aspx中的一个&lt;ASP:Button&gt;，用来显示效果。</p>
<p>Button2是Default5.aspx中的一个&lt;input type=button&gt;，用来触发JavaScript。</p>
<p>需求：点击Button2，将Button1上的文本改成&ldquo;from extended js&rdquo;</p>
<p> </p>
<p>方案一：使用内联JS访问器</p>
<p>要想在外部JS中获得ASPX动态生成的ClientID，可以通过在ASPX页面中添加访问器的方式来实现，类似OO语言中的属性：</p>
<p>我们在Default5.aspx中添加如下代码：作用：①声明getClientId访问器，并注册Button1的ClientID。②引用JScript.js文件</p>
<p>--&gt;&lt;script type=&quot;text/javascript&quot;&gt;<br>
&nbsp;&nbsp;&nbsp;  function getClientId()<br>
&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  var paraId1 = '&lt;%= Button1.ClientID %&gt;';<br>
&nbsp;&nbsp;&nbsp;&nbsp;  return {Id1:paraId1};<br>
&nbsp;&nbsp;&nbsp;  }<br>
&lt;/script&gt;<br>
&lt;script type=&quot;text/javascript&quot; src=&quot;JScript.js&quot;&gt;&lt;/script&gt; <br>
 </p>
<p>接下来，我们在JScript.js中，就可以这样来实现需求：</p>
<p>--&gt;function ChangeText()<br>
{<br>
&nbsp;&nbsp;&nbsp;  var btn=document.getElementById(getClientId().Id1);<br>
&nbsp;&nbsp;&nbsp;  btn.value=&quot;from extended js&quot;;<br>
} <br>
 </p>
<p>getClientId().Id1 貌似很OO，而且还支持VS2008很蹩脚的JS智能提示，打上&ldquo;.&rdquo;之后就可以在提示中选择Id1了。</p>
<p>如果有多个控件需要注册，只需将他们注册到访问器中即可，下面是一个完整的Demo代码：</p>
<p> </p>
<p>&gt;&lt;/script&gt;//引用外部js<br>
&lt;/asp:Content&gt;<br>
&lt;asp:Content ID=&quot;Content2&quot; ContentPlaceHolderID=&quot;ContentPlaceHolder1&quot; Runat=&quot;Server&quot;&gt;<br>
&nbsp;&nbsp;&nbsp;  &lt;asp:TextBox ID=&quot;TextBox1&quot; runat=&quot;server&quot;&gt;&lt;/asp:TextBox&gt;<br>
&nbsp;&nbsp;&nbsp;  &lt;asp:Button ID=&quot;Button1&quot; runat=&quot;server&quot; Text=&quot;Button&quot; /&gt;<br>
&nbsp;&nbsp;&nbsp;  &lt;input id=&quot;Button2&quot; type=&quot;button&quot; value=&quot;button&quot; onclick=&quot;ChangeText();&quot; /&gt;<br>
&lt;/asp:Content&gt;</p>
<p>function ChangeText()<br>
{<br>
&nbsp;&nbsp;&nbsp;  var btn=document.getElementById(getClientId().Id1);<br>
&nbsp;&nbsp;&nbsp;  btn.value=&quot;from extended js&quot;;<br>
&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  var btn=document.getElementById(getClientId().Id2);<br>
&nbsp;&nbsp;&nbsp;  btn.value=&quot;from extended js&quot;;<br>
}<br>
 </p>
<p>方案二：使用JS全局变量</p>
<p>还有一种方法也比较OO，就是使用JS全局变量，同样，也需要在Default5.aspx中添加一段JS代码，作为全局变量，来提供ClientID：</p>
<p>--&gt;&lt;script type=&quot;text/javascript&quot;&gt; </p>
<p>&nbsp;&nbsp;&nbsp;  var globals = {}; <br>
&nbsp;&nbsp;&nbsp;  globals.controlIdentities = {};<br>
&nbsp;&nbsp;&nbsp;  globals.controlIdentities.someControl1 = '&lt;%= Button1.ClientID %&gt;';<br>
&nbsp;&nbsp;&nbsp;  globals.controlIdentities.someControl2 = '&lt;%= TextBox1.ClientID %&gt;';<br>
&lt;/script&gt;<br>
&lt;script type=&quot;text/javascript&quot; src=&quot;JScript.js&quot;&gt;&lt;/script&gt; <br>
 </p>
<p>接下来，我们在JScript.js中，就可以这样来实现需求：</p>
<p>--&gt;function ChangeText()</p>
<p>{ <br>
&nbsp;&nbsp;&nbsp;  var btn=document.getElementById(globals.controlIdentities.someControl1);<br>
&nbsp;&nbsp;&nbsp;  btn.value=&quot;from extended js&quot;;<br>
} <br>
 </p>
<p>globals.controlIdentities.someControl1，同样，也支持VS2008很蹩脚的JS智能提示，打上&ldquo;.&rdquo;之后就可以在提示中选择someControl1了。下面是一个完整的Demo代码：</p>
<p> </p>
<p>&gt;&lt;/script&gt;<br>
&lt;/asp:Content&gt;<br>
&lt;asp:Content ID=&quot;Content2&quot; ContentPlaceHolderID=&quot;ContentPlaceHolder1&quot; Runat=&quot;Server&quot;&gt;<br>
&nbsp;&nbsp;&nbsp;  &lt;asp:TextBox ID=&quot;TextBox1&quot; runat=&quot;server&quot;&gt;&lt;/asp:TextBox&gt;<br>
&nbsp;&nbsp;&nbsp;  &lt;asp:Button ID=&quot;Button1&quot; runat=&quot;server&quot; Text=&quot;Button&quot; /&gt;<br>
&nbsp;&nbsp;&nbsp;  &lt;input id=&quot;Button2&quot; type=&quot;button&quot; value=&quot;button&quot; onclick=&quot;ChangeText();&quot; /&gt;<br>
&lt;/asp:Content&gt;</p>
<p><br>
function ChangeText()<br>
{<br>
&nbsp;&nbsp;&nbsp;  var btn=document.getElementById(globals.controlIdentities.someControl1);<br>
&nbsp;&nbsp;&nbsp;  btn.value=&quot;from extended js&quot;;<br>
&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  var txt=document.getElementById(globals.controlIdentities.someControl2);<br>
&nbsp;&nbsp;&nbsp;  btn.value=&quot;from extended js&quot;;<br>
}<br>
 </p>
<p>结束语：</p>
<p>在上面两种方法中，也没有真正的实现aspx和js的完全解耦，所以，在js文件中，最好还是加上：</p>
<p>--&gt;///&lt;reference path=&quot;Default5.aspx&quot;/&gt; <br>
上面的方法是我常用的，今天仓促的总结了一下，希望在此能够抛砖引玉，谢谢！</p>
<p> </p>
<p>--------------------------------------------------------------------------</p>
<p> </p>
<p>ASP.Net中如何使用ClientID</p>
<p> </p>
<p><br>
ASP.Net 提供了代码和页面分离的机制，在大多数情况下，这种机制工作得非常好。但是，如果需要使用客户端java脚本来做些工作，你就会遇到麻烦了。问题出在你在设计阶段为server端控件设置的ID值和页面运行时控件实际的ID值不一致。例如，新建一个Web site,增加一个 aspx page,在页面上加入一个text box控件：</p>
<p> &lt;asp:TextBox ID=&quot;mytext&quot; Runat=server&gt;&lt;/asp:TextBox&gt;&nbsp;&nbsp;&nbsp;  <br>
运行这个页面，从View source中会看到运行时的结果：</p>
<p> &lt;Input name=&quot;mytext&quot; type=&quot;text&quot; id=&quot;mytext&quot; /&gt;<br>
这时我们看到设计阶段的ID值和运行时控件的ID值是一样的，没有问题，这是因为这是一个单纯的aspx页面。如果在页面中包含一个用户自定义的web control或使用了master pages (ASP.NET 2.0)，情况就不乐观了。</p>
<p>我们增加一个新的user control名为mycontrol.ascx. 在mycontrol.ascx中加入同样的text box。再把这个自定义控件加入到一个aspx 页面， 将此控件的ID设置为myControl. 在浏览器中运行这个页面，得到的html是这样的：</p>
<p> &lt;Input name=&quot;myControl:mytext&quot; type=&quot;text&quot; id=&quot;myControl_mytext&quot; /&gt;<br>
text box控件的设计阶段ID= mytext，但运行时得到的ID=myControl_mytext。也就是在原来的ID前面增加了包含text box控件的容器myControl的ID。在使用master pages时，所有的aspx 页面都是被包含在一个容器中的， 而且还常常会有容器的嵌套。如果在客户端使用JavaScript去按照ID查找控件就会失败。解决这个问题可以有多个方法。</p>
<p>最简单的：</p>
<p>&lt;script language=&quot;javascript&quot; type =&quot;text/javascript&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var x=&lt;% Response.Write(&quot;'&quot;+myControl.ClientId+&quot;';&quot; ) %&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  function doSomething()<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Var myControl=document.getElementById(x);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&lt;/script&gt;</p>
<p>这种方法对于一个两个控件比较适用。不过由于必须在aspx页面中设置，不能将javascript集中起来管理了。</p>
<p>那么，有没有可以不进行硬编码的方法呢?本文提供了一种方法，可以使用ASP.Net现有技术实现，并且适合所有的ASP.Net framework版本。</p>
<p>解决方案<br>
关键是创建一个不会被服务器端修改的客户端控件。在自定义控件上增加一个hidden input，将它设为literal server side control：</p>
<p> &lt;input type=hidden id=&quot;ctrlPrefix&quot; name=&quot;ctrlPrefix&quot; value='&lt;asp:Literal Runat=server ID=ctrlPrefix&gt;&lt;/asp:Literal&gt;'&gt;<br>
还要注意，这个hidden input控件需要加入到控件容器里面。因为我们后面要用它来得到控件的ID。在后台代码中对Page_Load 事件加入如下处理：</p>
<p> string []elm =ctrlPrefix.ClientID.Split('_');&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p> ctrlPrefix.Text = ctrlPrefix.ClientID.Replace(elm[elm.Length - 1],&quot;&quot;);&nbsp;&nbsp;&nbsp;  <br>
我们得到控件的client id，包含了控件的ID加上控件容器的ID作为前缀。第二行代码将ctrlPrefix.ClientID的后面一段去掉，得到容器的ID前缀，返回值包含了_。编译后运行这个页面，结果如下：</p>
<p>&lt;input name=&quot;myControl:mytext&quot; type=&quot;text&quot; id=&quot;myControl_mytext&quot; /&gt;&lt;input type=hidden id=&quot;ctrlPrefix&quot; name=&quot;ctrlPrefix&quot; value='myControl_'&gt;  <br>
现在，hidden input中已经保存了容器的ID前缀。下面，我们用JavaScript来利用hidden input处理控件查找。</p>
<p>增加一个新的方法getCrtlPrefix()<br>
//returns the container prefix as all controls have that on their ids</p>
<p>function getCrtlPrefix()<br>
{<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var prefix;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  var&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  objCrtlPrefix = document.getElementById(&quot;ctrlPrefix&quot;);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (objCrtlPrefix)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  prefix = objCrtlPrefix.value;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  return prefix;<br>
}</p>
<p>这个方法得到hidden input的值并返回，这样我们就得到了ID的前缀。第二个方法用来查询空间</p>
<p>function readValue(ctrlName)<br>
{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
var prefix = getCrtlPrefix();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
var&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  objCrtl = document.getElementById(prefix + ctrlName);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (objCrtl)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  alert ( &quot;Prefix: &quot; + prefix + &quot; - value: &quot; + objCrtl.value);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  alert(&quot;not found!&quot;);<br>
}<br>
这个方法显示textbox控件的值。你会注意到，这里调用了getCtrlPrefix来计算textbox控件的ClientID。 我们可以增加一个按钮来调用这个方法：</p>
<p>&lt;input type=button value=&quot;Read Value&quot; onclick=&quot;javascript:readValue('mytext')&quot;&gt;<br>
这个html button会调用readValue。最后，把这个javascript的js文件加入aspx中。</p>
<p>&lt;script language=&quot;JavaScript&quot; src=&quot;mycontrol.js&quot;&gt;&lt;/script&gt;<br>
运行这个页面，在text box中输入写数据，然后点击按钮，会出现一个消息对话框来显示ID前缀以及text box中的数据。</p>
<p> </p>
<p>本文来自CSDN博客，出处：<a href="http://blog.csdn.net/jamestaosh/archive/2009/07/22/4370127.aspx">http://blog.csdn.net/jamestaosh/archive/2009/07/22/4370127.aspx</a></p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/asp%2Enet">asp.net</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/8901f4361d93253b0b55a929.html#comment">查看评论</a>]]></description>
        <pubDate>2009年10月16日 星期五  22:27</pubDate>
        <category><![CDATA[asp.net]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/8901f4361d93253b0b55a929.html</guid>
</item>

<item>
        <title><![CDATA[[转]ViewState 探究]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/c1bf261fea309ec2a6866992.html]]></link>
        <description><![CDATA[
		
		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  实际上ViewState并不神秘，就是一个Hidden字段，但是它是服务器控件状态保存的基础；不熟悉的朋友可以用IE查看Html源码，找到一个名为&quot;__VIEWSTATE&quot;的Hidden字段，其中有一大堆乱七八糟的字符，这就是页面的ViewState。<br>
<br>
  &nbsp;&nbsp;&nbsp; 做过Web程序的人可能都有这种痛苦的体会，有时候为了处理页面上面比较复杂的功能，常常会加很多Hidden，然后在服务器端用一大堆判断来分析目前的状态，写起来烦人，写完了代码更是难看；实际上，ViewState就是帮我们系统的实现了保存控件状态的功能，服务器端控件能够在多次请求间保存状态也全靠它。<br>
    好，介绍就到这里，今天我们不是讨论ViewState的使用，而是从内部来探探这个东西的本质。<br>
&nbsp;&nbsp; 我们首先建一个测试的页面：<br>
&nbsp;&nbsp; &lt;%@ Page language=&quot;c#&quot; Codebehind=&quot;ViewStateTest.aspx.cs&quot; AutoEventWireup=&quot;false&quot; Inherits=&quot;CsdnTest.ViewStateTest&quot; %&gt;<br>
&nbsp;&nbsp; &lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0 Transitional//EN&quot; &gt;<br>
&nbsp;&nbsp; &lt;html&gt;<br>
    &lt;head&gt;<br>
&nbsp;&nbsp; &lt;title&gt;ViewStateTest&lt;/title&gt;<br>
&nbsp;&nbsp; &lt;meta name=&quot;GENERATOR&quot; Content=&quot;Microsoft Visual Studio 7.0&quot;&gt;<br>
&nbsp;&nbsp; &lt;meta name=&quot;CODE_LANGUAGE&quot; Content=&quot;C#&quot;&gt;<br>
&nbsp;&nbsp; &lt;meta name=&quot;vs_defaultClientScript&quot; content=&quot;javascript&quot;&gt;<br>
&nbsp;&nbsp; &lt;meta name=&quot;vs_targetSchema&quot; content=&quot;http://schemas.microsoft.com/intellisense/ie5&quot;;&gt;<br>
    &lt;/head&gt;<br>
&lt;body&gt;<br>
&nbsp;&nbsp; &lt;form id=&quot;ViewStateTest&quot; method=&quot;post&quot; runat=&quot;server&quot;&gt;<br>
&nbsp;&nbsp; &lt;asp:Button ID=&quot;btnPostBack&quot; Runat=&quot;server&quot; Text=&quot;Post Back&quot; Width=&quot;85px&quot;&gt;&lt;/asp:Button&gt;<br>
&nbsp;&nbsp; &lt;br/&gt;<br>
&nbsp;&nbsp; &lt;asp:CheckBox ID=&quot;chkTest&quot; Runat=&quot;server&quot; Text=&quot;This is a check box&quot;&gt;&lt;/asp:CheckBox&gt;<br>
&nbsp;&nbsp; &lt;/form&gt;<br>
&lt;/body&gt;<br>
&nbsp;&nbsp; &lt;/html&gt;<br>
<br>
<div class="t_msgfont">这是用Vs.Net设计出来的一个简单的页面，里面包含了一个服务器端的按钮和一个CheckBox，然后我们在服务器端响应按钮的事件：<br>
<br>
   private void btnPostBack_Click(object sender, System.EventArgs e)<br>
   {<br>
[1] Response.Write( &quot;ViewState :&quot;+Request.Params[&quot;__VIEWSTATE&quot;]+&quot;&lt;br/&gt;&quot; );<br>
&nbsp;&nbsp;<br>
[2] string decodevalue = Encoding.UTF8.GetString( Convert.FromBase64String( Request.Params[&quot;__VIEWSTATE&quot;] ) );<br>
    <br>
[3] Response.Write( &quot;ViewState decode :&quot;+decodevalue+&quot;&lt;br/&gt;&quot; );<br>
<br>
[4] object viewstate = (new LosFormatter()).Deserialize( Request.Params[&quot;__VIEWSTATE&quot;] );<br>
<br>
[5] Response.Write( &quot;ViewState Object :&quot;+viewstate.GetType().Name );<br>
   }<br>
<br>
   为了方便看，我加上了行号；第一行我们把ViewState的值打出来，第二行是什么呢？实际上ViewState保存到客户端的一串字符串就是内部的ViewState通过某种方式序列化之后再经过Base64编码得来的，所以我们把Base64编码的字符串反编码一次再打出来；至于第四行，我先不说，先看执行结果：<br>
   运行之后，页面上什么都没有，除了按钮和CheckBox（废话 ：）），我们点击按钮，然后结果如下：<br>
<br>
&nbsp;&nbsp; [A]   ViewState :DDwxMjU2MDI5MTA3OztsPGNoa1Rlc3Q7Pj6Gg0Qzm+7gacYWcy0hnRCT9toOdA==<br>
&nbsp;&nbsp; [B]   ViewState decode:t&lt;1256029107;;l&gt;D3i s-! t<br>
&nbsp;&nbsp; [C]   ViewState Object :Triplet <br>
<br>
   然后我们来分析这个结果，A中显示的就是ViewState传到客户端的值，B中显示的是通过Base64反编码之后的值，从这里面好像还是看不出什么，C中出现了一个:Triplet ？这是什么呢，我们回到上面的代码：<br>
  &nbsp;&nbsp;   object viewstate = (new LosFormatter()).Deserialize( Request.Params[&quot;__VIEWSTATE&quot;] );<br>
<br>
   注意我们使用了一个LosFormatter类，实际上这个类就是Asp.Net内部为ViewState提供序列化的类，它有两个方法，一个是Serialize，就是序列化一个对象，一个是Deserialize，是反序列化，我们这里使用了反序列化的方法来把ViewState直接反序列化成一个对象，然后把这个对象的类型打出来，这个对象就是:Triplet类型，实际上Asp.Net中页面保存的ViewState就是这个类型，我们先分析一下LosFormater，再来细说.<br>
   我们再回来看打出来的结果B：t&lt;1256029107;;l&gt;D3i s-!&nbsp;&nbsp;<br>
t，实际上通过查看LosFormatter反编译后的代码，大致上可以看出它序列化的方式是很简单的，就是判断要序列化对象的类型，如果不是直接序列化的类型，则把它的类型记录下来，然后在递归序列化它的属性，我们看B中的&quot;t&quot;就是表示Triplet这个类型，这个类型有三个属性，这三个属性包含在&quot;&lt;&quot;和&quot;&gt;&quot;之间，用&quot;;&quot;分割，而最后面的D3i s-!&nbsp;&nbsp;<br>
t据我分析应该是一个防止ViewState被改变的Hash值，这个不是很确定，因为反编译的代码实在是很难看，我只是了解之后就没仔细看了。<br>
<br>
   我们刚刚分析出来Page中的ViewState反序列化之后是Triplet这个类型，实际上这个类在MSDN中就查得到，它就是一个包含了三个对象的对象，说简单点，它就是一个能放三个箱子的大箱子（好像还是说的比较糊涂，呵呵），它有三个属性：First、Second、Thrid ：），分别代表三个对象。<br>
   对应到Page当中，First是Page.GetTypeHashCode()的返回值，这个方法是System.Web.UI.Page定义的一个保护的虚拟方法，返回一个整型，由Aspx文件生成的类来实现的，因为这个类是有Asp.Net负责在运行期生成源代码并编译，它会计算出一个大常量作为返回值，这个返回值在整个Web应用程序所有的Page中是唯一的。（提一句题外话，Asp.Net自动产生的源代码可以到 系统盘:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\Temporary ASP.NET Files下面去找），这个唯一的Hash值是为了在ViewState中产生一个标记，使这个ViewState只适用与对应的页面。<br>
   Second则是通Control.SaveViewStateRecursive方法递归保存页面控件树的ViewState返回的对象，也就是真正的ViewState的数据。<br>
   Third中保存的是当前页面需要PostBack的控件名的列表。<br>
   <br>
<br>
   分析了页面的ViewState的构成，我们再来看Control的ViewState的实现。ViewState是System.Web.UI.Control类实现的一个属性，这个属性的类型是System.Web.UI.StateBag，这个类就包含了ViewState数据结构的实现，实际上它的内部也就是个Hash表，通过Key值来保存和检索数据。<br>
&nbsp;&nbsp; 那么服务器控件是怎么实现保存状态的呢？<br>
&nbsp;&nbsp; 我们知道，所有的服务器控件都是从System.Web.UI.Control派生的，所以都拥有ViewState这个属性，在Control内部，定义了两个Protected的虚拟方法：<br>
    protected virtual object SaveViewState() <br>
&nbsp;&nbsp; 和<br>
protected virtual void LoadViewState(object savedState) <br>
<br>
&nbsp;&nbsp; 这两个方法是给子控件派生用来保存和读取自己的ViewState的，比如我们有一个自己写的控件，往ViewState中保存了一个字符串，那么我们的方法大致像这样：<br>
    protected virtual object SaveViewState()<br>
    {<br>
  &nbsp;&nbsp;    object[] states = new object[2];<br>
  &nbsp;&nbsp;    states[0] = base.SaveViewState();  &nbsp;&nbsp;   //记得保存父控件的ViewState<br>
  &nbsp;&nbsp;    states[1] = &quot;Hello,I'm timmy!&quot;;  &nbsp;&nbsp;  &nbsp;&nbsp;&nbsp; //这里保存我们自己的<br>
  &nbsp;&nbsp;   <br>
  &nbsp;&nbsp;    return states; //返回重新包装后的保存对象<br>
    }<br>
    获取的时候：<br>
    protected override void LoadViewState(object savedState)&nbsp;&nbsp; //这里的savedState就是我们Save的时候return 的object数组<br>
    {<br>
  &nbsp;&nbsp;    object[] states = (object[])savedState;<br>
  &nbsp;&nbsp;    base.LoadViewState( states[0] );   //把父类的数据给他自己去解析<br>
  &nbsp;&nbsp;    string myData = (string)states[1];&nbsp;&nbsp; //获取我们自己的数据<br>
    }<br>
   我们可以按照自己的方式来保存，不一定非要像上面这样用数组，实际上我们可以用任何支持序列化的对象都可以，父类并不关心子类如何保存，我们只要在Save和Load的时候使用同样的方式，并且把正确的数据传递给父类方法就可以了。<br>
   <br>
   另外，还有一个问题就是我们使用的Control的ViewState是Key-value这样的键值对，那它是怎么保存的呢？<br>
   实际上很简单，System.UI.Web下面有一个类叫Pair，呵呵，这个和Triplet差不多，只是它里面只有两个对象。StateBag保存的时候，First会存放所有Key值的数组，Second则存放所有value的数组。<br>
<br>
   到现在，我们了解了ViewState是如何序列化并且保存到客户端，也了解了控件怎么保存自己的ViewState，那么这二者是怎么结合的呢？<br>
<br>
也就是整个页面的控件树的ViewState是怎么保存和读取的呢？<br>
<br>
   在Control内部有两个internal的方法：<br>
   internal object SaveViewStateRecursive()；<br>
   internal void LoadRecursive()；<br>
   这两个方法由System.Web.UI.Page来调用，Page在Render结束后就会调用SavePageViewState方法，SavePageViewState方法会调用Control的SaveViewStateRecursive()方法，这个方法就是通过递归调用每一个Control.Controls的SaveViewStateRecursive方法来保存控件树中所有控件的ViewState。到这里，可能聪明的朋友要问了，既然SaveViewStateRecursive是递归调用保存的方法，那么我们上面写的SaveViewState()方法又有什么用呢？<br>
   我们知道，Control.Controls可能会有很多个，而且我们的SaveViewState()只保存了当前控件的数据，而没有记录控件树的结构，那么如果我们递归SaveViewState()方法来保存数据的话，那么控件树的结构就会丢失，那么Load的时候就没办法还原了，实际上在SaveViewStateRecursive方法中大致的代码是这样：<br>
    [1] 获取控件自己的ViewState（调用SaveViewState方法）<br>
    [2] 循环子控件<br>
  &nbsp;&nbsp;&nbsp; {<br>
  &nbsp;&nbsp;  &nbsp;&nbsp;   定义两个动态数组，一个保存控件的索引，一个保存递归调用子控件SaveViewStateRecursive方法返回的值<br>
  &nbsp;&nbsp;&nbsp; }<br>
    [3] 定义一个Triplet（呵呵，这个东西又出现了）<br>
    [4] First保存本控件的ViewState<br>
    [5] Second保存子控件的索引<br>
    [6] Third保存递归子控件SaveViewStateRecursive方法的返回值<br>
    [7] 返回Triplet<br>
   这样就保存了整个控件树的ViewState和控件树的结构<br>
<br>
   Load的方式与Save差不多，只是Load的时候会从savedState中获取子控件的索引来依次递归子控件的LoadRecursive()方法，这样才能保证正确的把保存的数据传给子控件。<br>
<br>
<br>
   到这里，ViewState的实现我们大致了解了一下，最后得出一些结论：<br>
   1、ViewState是存放在客户端，因此会减轻服务器的负担，是一种比较好的保存数据的方式。<br>
   2、因为ViewState本身的限制，只能保存可以序列化的对象，而且最好不要放太多东西，能省则省，以免在减慢传输的速度，以及加重服务器解析的负担。<br>
   3、我们通过很简单的方式就可以把ViewState里面的值获取出来，我们上面讨论了一些，虽然没有把解析的代码写出来，但是利用LosFormatter可以得到ViewState反序列化后的对象，那么要解析出来简直是易如反掌；所以ViewState在安全性上面还是比较差，建议不要<br>
存放比较机密和敏感的信息，尽管ViewState可以加密，但是由于ViewState要保存在客户端，天生就有安全性的隐患。<br>
   4、实际从技术角度，ViewState没有任何新意，但是结合服务器控件的设计还是很巧妙的。<br>
   <br>
   最后，以我个人的观点，我觉得ViewState的出现很大程度上减轻了程序员的负担，但是要看清的是ViewState的本质，合理的应用它。<br>
<br>
简述：<br>
ViewState:<br>
    相当于页面的一个隐藏Web控件<br>
    他不会过期<br>
    占用的资源少（可以用它，就用它）<br>
Session:<br>
    比较好资源。<br>
    会话模式。<br>
    通常用于保存保存登陆帐号什么的。<br>
    一次赋值后只要没有超过时间，可以直接在其他页面直接用。</div> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/asp%2Enet">asp.net</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/c1bf261fea309ec2a6866992.html#comment">查看评论</a>]]></description>
        <pubDate>2009年10月12日 星期一  09:23</pubDate>
        <category><![CDATA[asp.net]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/c1bf261fea309ec2a6866992.html</guid>
</item>

<item>
        <title><![CDATA[MSDN格式字符串说明文档]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/ff0518d50350e3ce50da4b5e.html]]></link>
        <description><![CDATA[
		
		<br>
数字格式字符串：<a href="http://msdn.microsoft.com/zh-cn/library/dwhawy9k.aspx">http://msdn.microsoft.com/zh-cn/library/dwhawy9k.aspx</a><br>
日期与时间格式字符串：<a href="http://msdn.microsoft.com/zh-cn/library/97x6twsz.aspx">http://msdn.microsoft.com/zh-cn/library/97x6twsz.aspx</a><br>
枚举格式字符串：<a href="http://msdn.microsoft.com/zh-cn/library/c3s1ez6e.aspx">http://msdn.microsoft.com/zh-cn/library/c3s1ez6e.aspx</a> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/Csharp">Csharp</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/ff0518d50350e3ce50da4b5e.html#comment">查看评论</a>]]></description>
        <pubDate>2009年10月05日 星期一  13:12</pubDate>
        <category><![CDATA[Csharp]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/ff0518d50350e3ce50da4b5e.html</guid>
</item>

<item>
        <title><![CDATA[c# 泛型集合Dictionary&#60;TKey,TValue&#62;]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/3ae24a54de253d5d574e0066.html]]></link>
        <description><![CDATA[
		
		<p style="text-indent: 2em">泛型最常见的用途是泛型集合，命名空间System.Collections.Generic 中包含了一些基于泛型的集合类，使用泛型集合类可以提供更高的类型安全性，还有更高的性能，避免了非泛型集合的重复的装箱和拆箱。</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  很多非泛型集合类都有对应的泛型集合类，我觉得最好还是养成用泛型集合类的好习惯，他不但性能上好而且 功能上要比非泛型类更齐全。下面是常用的非泛型集合类以及对应的泛型集合类：</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp; 
<table cellspacing="1" cellpadding="1" width="583" border="1">
    <tbody>
        <tr>
            <td>非泛型集合类</td>
            <td>泛型集合类</td>
        </tr>
        <tr>
            <td>ArrayList</td>
            <td>List&lt;T&gt;</td>
        </tr>
        <tr>
            <td>HashTable</td>
            <td>DIctionary&lt;T&gt;</td>
        </tr>
        <tr>
            <td>Queue</td>
            <td>Queue&lt;T&gt;</td>
        </tr>
        <tr>
            <td>Stack</td>
            <td>Stack&lt;T&gt;</td>
        </tr>
        <tr>
            <td>SortedList</td>
            <td>SortedList&lt;T&gt;</td>
        </tr>
    </tbody>
</table>
</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  我们用的比较多的非泛型集合类主要有  ArrayList类 和 HashTable类，其中当我们经常性的操作 数据信息时往往用HashTable 来存储将要写入到数据库或者返回的信息，在这之间要不断的进行类型的转化，他给我们的帮助应该是非常大的，如果我们操纵的数据类型相对确定的化  用Dictionary&lt;TKey,TValue&gt;集合类来存储数据就方便多了，例如我们需要在电子商务网站中存储用户的购物车信息( 商品名，对应的商品个数)时，完全可以用Dictionary&lt;string,int &gt; 来存储购物车信息，而不需要任何的类型转化。</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面是简单的例子，包括声明，填充键值对，移除键值对，遍历键值对</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dictionary&lt;string, string&gt; myDic = new Dictionary&lt;string, string&gt;();</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  myDic.Add(&quot;aaa&quot;, &quot;111&quot;);</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  myDic.Add(&quot;bbb&quot;, &quot;222&quot;);</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  myDic.Add(&quot;ccc&quot;, &quot;333&quot;);</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  myDic.Add(&quot;ddd&quot;, &quot;444&quot;);</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //如果添加已经存在的键，add方法会抛出异常</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  try</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  myDic.Add(&quot;ddd&quot;,&quot;ddd&quot;);</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  catch (ArgumentException ex)</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(&quot;此键已经存在：&quot; + ex.Message);</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //解决add()异常的方法是用ContainsKey()方法来判断键是否存在</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (!myDic.ContainsKey(&quot;ddd&quot;))</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  myDic.Add(&quot;ddd&quot;, &quot;ddd&quot;);</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  else</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(&quot;此键已经存在：&quot;);</p>
<p style="text-indent: 2em"> </p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //而使用索引器来负值时，如果建已经存在，就会修改已有的键的键值，而不会抛出异常</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  myDic [&quot;ddd&quot;]=&quot;ddd&quot;;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  myDic[&quot;eee&quot;] = &quot;555&quot;;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //使用索引器来取值时，如果键不存在就会引发异常</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  try</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(&quot;不存在的键\&quot;fff\&quot;的键值为：&quot; + myDic[&quot;fff&quot;]);</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  catch (KeyNotFoundException ex)</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(&quot;没有找到键引发异常：&quot; + ex.Message);</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //解决上面的异常的方法是使用ContarnsKey() 来判断时候存在键，如果经常要取健值得化最好用 TryGetValue方法来获取集合中的对应键值</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  string value = &quot;&quot;;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (myDic.TryGetValue(&quot;fff&quot;, out value))</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(&quot;不存在的键\&quot;fff\&quot;的键值为：&quot; + value );</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  else</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(&quot;没有找到对应键的键值&quot;);</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //下面用foreach 来遍历键值对</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //泛型结构体 用来存储健值对</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  foreach (KeyValuePair&lt;string, string&gt; kvp in myDic)</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(&quot;key={0},value={1}&quot;, kvp.Key, kvp.Value);</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //获取值得集合</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  foreach (string s in myDic.Values)</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(&quot;value={0}&quot;, s);</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //获取值得另一种方式</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Dictionary&lt;string, string&gt;.ValueCollection values = myDic.Values;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  foreach (string s in values)</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(&quot;value={0}&quot;, s);</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    //获取键的集合和获取值得集合类似</p>
<p style="text-indent: 2em">&nbsp;&nbsp;</p>
<p style="text-indent: 2em">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  常用的属性和方法如下：
<table cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em">常用属性</p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">属性说明</p>
            </td>
        </tr>
        <tr>
            <td width="2%"> </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/ms132092(VS.80).aspx"><font color="#64a038">Comparer</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">获取用于确定字典中的键是否相等的 <a href="http://msdn2.microsoft.com/zh-cn/library/ms132151(VS.80).aspx"><font color="#64a038">IEqualityComparer</font></a>。</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/zhcy256f(VS.80).aspx"><font color="#64a038">Count</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">获取包含在 Dictionary 中的键/值对的数目。</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/9tee9ht2(VS.80).aspx"><font color="#64a038">Item</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">获取或设置与指定的键相关联的值。</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/yt2fy5zk(VS.80).aspx"><font color="#64a038">Keys</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">获取包含 Dictionary 中的键的集合。</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/ekcfxy3x(VS.80).aspx"><font color="#64a038">Values</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">获取包含 Dictionary 中的值的集合。</p>
            </td>
        </tr>
        <tr>
            <td width="2%"> </td>
            <td width="19%">常用的方法</td>
            <td width="78%">方法说明</td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/k7z0zy8k(VS.80).aspx"><font color="#64a038">Add</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">将指定的键和值添加到字典中。</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/b5txwy7s(VS.80).aspx"><font color="#64a038">Clear</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">从 Dictionary 中移除所有的键和值。</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/kw5aaea4(VS.80).aspx"><font color="#64a038">ContainsKey</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">确定 Dictionary 是否包含指定的键。</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/a63811ah(VS.80).aspx"><font color="#64a038">ContainsValue</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">确定 Dictionary 是否包含特定值。</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/system.object.equals(VS.80).aspx"><font color="#64a038">Equals</font></a> </p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">已重载。 确定两个 <a href="http://msdn2.microsoft.com/zh-cn/library/system.object(VS.80).aspx"><font color="#64a038">Object</font></a> 实例是否相等。 （从 <a href="http://msdn2.microsoft.com/zh-cn/library/system.object(VS.80).aspx"><font color="#64a038">Object</font></a> 继承。）</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/9c6ftx8b(VS.80).aspx"><font color="#64a038">GetEnumerator</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">返回循环访问 Dictionary 的枚举数。</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/system.object.gethashcode(VS.80).aspx"><font color="#64a038">GetHashCode</font></a> </p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">用作特定类型的哈希函数。<a href="http://msdn2.microsoft.com/zh-cn/library/system.object.gethashcode(VS.80).aspx"><font color="#64a038">GetHashCode</font></a> 适合在哈希算法和数据结构（如哈希表）中使用。 （从 <a href="http://msdn2.microsoft.com/zh-cn/library/system.object(VS.80).aspx"><font color="#64a038">Object</font></a> 继承。）</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/yy8be3bb(VS.80).aspx"><font color="#64a038">GetObjectData</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">实现 <a href="http://msdn2.microsoft.com/zh-cn/library/system.runtime.serialization.iserializable(VS.80).aspx"><font color="#64a038">System.Runtime.Serialization.ISerializable</font></a> 接口，并返回序列化 Dictionary 实例所需的数据。</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/system.object.gettype(VS.80).aspx"><font color="#64a038">GetType</font></a> </p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">获取当前实例的 <a href="http://msdn2.microsoft.com/zh-cn/library/system.type(VS.80).aspx"><font color="#64a038">Type</font></a>。 （从 <a href="http://msdn2.microsoft.com/zh-cn/library/system.object(VS.80).aspx"><font color="#64a038">Object</font></a> 继承。）</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/t71h85y4(VS.80).aspx"><font color="#64a038">OnDeserialization</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">实现 System.Runtime.Serialization.ISerializable 接口，并在完成反序列化之后引发反序列化事件。</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/system.object.referenceequals(VS.80).aspx"><font color="#64a038">ReferenceEquals</font></a> </p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">确定指定的 Object 实例是否是相同的实例。 （从 <a href="http://msdn2.microsoft.com/zh-cn/library/system.object(VS.80).aspx"><font color="#64a038">Object</font></a> 继承。）</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/kabs04ac(VS.80).aspx"><font color="#64a038">Remove</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">从 Dictionary 中移除所指定的键的值。</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/system.object.tostring(VS.80).aspx"><font color="#64a038">ToString</font></a> </p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">返回表示当前 Object 的 <a href="http://msdn2.microsoft.com/zh-cn/library/system.string(VS.80).aspx"><font color="#64a038">String</font></a>。 （从 <a href="http://msdn2.microsoft.com/zh-cn/library/system.object(VS.80).aspx"><font color="#64a038">Object</font></a> 继承。）</p>
            </td>
        </tr>
        <tr>
            <td width="2%">
            <p> </p>
            <p style="text-indent: 2em"> </p>
            </td>
            <td width="19%">
            <p> </p>
            <p style="text-indent: 2em"><a href="http://msdn2.microsoft.com/zh-cn/library/zkw5c9ak(VS.80).aspx"><font color="#64a038">TryGetValue</font></a></p>
            </td>
            <td width="78%">
            <p> </p>
            <p style="text-indent: 2em">获取与指定的键相关联的值。</p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p style="text-indent: 2em"> </p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/Csharp">Csharp</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/3ae24a54de253d5d574e0066.html#comment">查看评论</a>]]></description>
        <pubDate>2009年08月29日 星期六  15:37</pubDate>
        <category><![CDATA[Csharp]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/3ae24a54de253d5d574e0066.html</guid>
</item>

<item>
        <title><![CDATA[IIS 备份与还原]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/55337e1ede51d3fd1ad57621.html]]></link>
        <description><![CDATA[
		
		<p>文件&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  用途<br>
systemroot\System32\Inetsrv\MetaBase.xml&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  存储 IIS 服务的配置数据。</p>
<p>systemroot\System32\Inetsrv\MBSchema.xml&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  存储配置文件的架构。架构定义了在某些配置数据库节点可设置哪些 IIS 属性。</p>
<p>systemroot\System32\Inetsrv\History\History File&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  存储由 IIS 自动创建的配置数据库历史文件。</p>
<p>systemroot\System32\Inetsrv\MetaBack\Backup File&nbsp;&nbsp;  存储通过使用&ldquo;备份/还原配置&rdquo;功能按需创建的配置数据库备份文件。</p>
<p>从历史文件还原配置数据库</p>
<p>当启用了历史功能时，IIS 会定期创建名为历史文件的备份文件。历史文件是配置数据库配置文件 (MetaBase.xml) 和与之匹配的配置数据库架构文件 (MBSchema.xml) 的副本。从历史文件还原配置数据库的过程类似于从备份文件还原配置数据库。<br>
 要点 您必须是本地计算机上 Administrators 组的成员或者必须被委派了相应的权限，才能执行下列步骤。作为安全性的最佳操作，请使用不属于 Administrators 组的帐户登录计算机，然后使用运行方式命令以管理员身份运行 IIS 管理器。在命令提示符下，键入 runas /user:administrative_accountname &quot;mmc %systemroot%\system32\inetsrv\iis.msc&quot;。<br>
使用 IIS 管理器还原配置数据库</p>
<p>在 IIS 管理器中，右键单击本地计算机，指向&ldquo;所有任务&rdquo;，然后单击&ldquo;备份/还原配置&rdquo;。 <br>
在&ldquo;备份&rdquo;列表中，单击要还原的&ldquo;自动备份&rdquo;，然后单击&ldquo;还原&rdquo;。 <br>
如果要继续，请阅读出现的消息，然后单击&ldquo;是&rdquo;。 <br>
单击&ldquo;确定&rdquo;。 <br>
有时候可能需要在不使用 IIS 管理器的情况下还原配置数据库。例如，如果配置更改不当或者更改时出现了可扩展标记语言 (XML) 语法错误，且 IIS 管理器无法枚举配置数据库，请使用下列步骤还原配置数据库：<br>
手动还原配置数据库<br>
打开命令提示符窗口。从&ldquo;开始&rdquo;菜单，单击&ldquo;运行&rdquo;。 <br>
在&ldquo;打开&rdquo;框中，键入 cmd，然后单击&ldquo;确定&rdquo;。 <br>
停止 IIS 服务。在命令提示符处，键入 iisreset /stop，然后按 Enter。命令提示符窗口将显示下列内容：<br>
正在尝试停止...<br>
Internet 服务已成功停止<br>
如果 IIS 服务不停止，且可能要重新启动计算机，请键入 iisreset /stop /rebootonerror，然后按 Enter。 <br>
创建当前配置数据库文件的副本。在命令提示符处，键入 cd systemroot\System32\Inetsrv，然后按 Enter 以找到配置数据库文件所在的文件夹。接下来，键入 copy MBSchema.xml MBSchema.old，然后按 Enter 以复制架构文件。最后，键入 copy MetaBase.xml Metabase.old，然后按 Enter 以复制配置数据库配置文件。 <br>
查找配置数据库历史文件。在命令提示符处，键入 cd systemroot\System32\Inetsrv\History，然后按 Enter。 <br>
选择所需的历史文件版本。在命令提示符处，键入 dir，然后按 Enter。所有的文件都按如下格式显示： <br>
&lt;date&gt;  &lt;time&gt;&nbsp;&nbsp;  &lt;file size&gt; MBSchema_&lt;identifying number&gt;_0000000000.xml<br>
&lt;date&gt;  &lt;time&gt;&nbsp;&nbsp;  &lt;file size&gt; MetaBase_&lt;identifying number&gt;_0000000000.xml</p>
<p>当将 IIS 配置数据库还原到早期版本时，您需要相匹配的配置数据库架构文件和配置数据库配置文件。通过文件的标识号来选择匹配文件。 <br>
将所选历史架构文件复制到现有的配置数据库架构中。在命令提示符处，键入 copy /y MBSchema_&lt;identifying number&gt;_0000000000.xml systemroot\System32\Inetsrv\MBSchema.xml，然后按 Enter。使用该命令，您可以在复制文件的同时对其重新命名。 <br>
将匹配的历史配置文件复制到现有的配置数据库配置中。在命令提示符处，键入 copy /y Metabase_&lt;identifying number&gt;_0000000000.xml systemroot\System32\Inetsrv\MetaBase.xml，然后按 Enter。同样，该命令复制文件并同时对其重新命名。 <br>
 要点 如果您混淆了名称或复制了不匹配的架构和配置文件，当启动 IIS 服务时，配置数据库还原将失败。</p>
<p>重新启动 IIS。在命令提示符处，键入 iisreset /start，然后按 Enter。命令提示符处显示下列内容：<br>
正在尝试启动...<br>
Internet 服务已成功启动<br>
如果 IIS 服务不重新启动，请从第 4 步开始重复上述步骤，然后将另一组历史文件复制到当前的配置数据库文件中。 <br>
从备份文件还原配置数据库<br>
IIS 管理员可以使用 IIS 管理器或命令行管理脚本创建备份文件。备份文件是配置数据库配置文件 (MetaBase.xml) 和与之匹配的配置数据库架构文件 (MBSchema.xml) 的便携式副本。通过使用配置数据库配置的备份/还原功能，可以从备份文件还原配置数据库。</p>
<p>备份 IIS 配置数据库<br>
使用配置的备份/还原功能，可创建 IIS 配置数据库的完整备份副本。配置数据库的备份文件提供一种在数据库被破坏时还原配置数据库配置和架构数据的方法。备份文件可还原到创建备份的计算机上，也可以还原到安装了 Windows Server 2003 家族的其他计算机上。</p>
<p>备份文件只包含配置数据；不包括内容。要同时备份内容，请使用 Windows 备份功能。详细信息，请参阅备份和还原数据。</p>
<p> 注意 配置数据库在备份过程中处于锁定状态。</p>
<p>安全备份<br>
当创建安全备份时，管理员提供一个 IIS 用来加密备份文件的密码。密码被加密并存储在备份文件的标头中。只加密备份文件中的管理员密码和安全属性；备份文件中的所有其他信息都是纯文本。在加密备份文件之后，不能更改备份文件中的密码。</p>
<p>不安全备份<br>
当创建不安全的备份时，管理员不提供密码。因此，不安全的备份文件用空密码加密，Administrators 组的任何成员都能使用不安全的备份文件还原配置数据库。只加密空密码和安全属性；备份文件中的所有其他信息都是纯文本。</p>
<p> 要点 您必须是本地计算机上 Administrators 组的成员或者必须被委派了相应的权限，才能执行下列步骤。作为安全性的最佳操作，请使用不属于 Administrators 组的帐户登录计算机，然后使用运行方式命令以管理员身份运行 IIS 管理器。在命令提示符下，键入 runas /user:administrative_accountname &quot;mmc %systemroot%\system32\inetsrv\iis.msc&quot;。</p>
<p>备份 IIS 配置数据库</p>
<p>在 IIS 管理器中，右键单击本地计算机，指向&ldquo;所有任务&rdquo;，然后单击&ldquo;备份/还原配置&rdquo;。 <br>
单击&ldquo;创建备份&rdquo;，然后在&ldquo;配置备份名称&rdquo;框中键入备份文件的名称。请注意，备份文件名是不区分大小写的。 <br>
可选：如果要创建安全备份，请选中&ldquo;使用密码加密备份&rdquo;复选框，在&ldquo;密码&rdquo;框中键入密码，然后在&ldquo;确认密码&rdquo;框中键入相同的密码。 <br>
单击&ldquo;确定&rdquo;。</p>
<p>在创建备份时，会创建两个采用如下格式命名的文件：<br>
name.mdx<br>
name.scx<br>
其中 name 是管理员用来命名备份集的名称，x 是备份集的版本号，从 0（零）开始。版本号对于每个使用相同名称的备份集按 1 递增。例如，如果两次都使用 mybackup 名称作为备份集名称，则在第一次备份时创建的文件是 mybackup.md0 和 mybackup.sc0；在第二次备份时，文件名为 mybackup.md1 和 mybackup.sc1。在默认情况下，备份文件存储在 systemroot\System32\Inetsrv\MetaBack 文件夹中。</p>
<p>还原 IIS 配置数据库备份<br>
可将配置数据库备份还原到创建备份的同一台计算机上，也可以还原到其他计算机上。因为配置数据库备份不包括内容文件，所以，如果要将配置数据库备份还原到其他服务器上，还必须复制内容文件。内容文件所在的位置和驱动器必须与原服务器相同。不支持从早期版本的 IIS 中还原备份。</p>
<p> 要点 在将配置数据库从一台计算机还原到另一台计算机之前，必须首先从配置数据库文件中删除计算机特定的信息。有关该问题的重要信息，请参阅计算机和系统特定的信息和复制 IIS 配置。</p>
<p>还原 IIS 配置数据库备份</p>
<p>在 IIS 管理器中，右键单击本地计算机，指向&ldquo;所有任务&rdquo;，然后单击&ldquo;备份/还原配置&rdquo;。 <br>
在&ldquo;备份&rdquo;列表中，单击要还原的备份，然后单击&ldquo;还原&rdquo;。 <br>
 注意 如果希望将 IIS 还原到初始配置，请还原由 IIS 安装程序自动创建的名为&ldquo;初始备份&rdquo;的备份。</p>
<p>如果要继续，请阅读出现的消息，然后单击&ldquo;是&rdquo;。 <br>
如果要还原安全备份，系统将提示您输入在创建备份时键入的密码。键入该密码，然后单击&ldquo;确定&rdquo;。请注意，密码是区分大小写的。 <br>
单击&ldquo;确定&rdquo;。</p>
<p>SSL 证书<br>
如果在 Web 服务器上使用安全套节字层 (SSL) 证书，并将配置数据库备份还原到安装的其他操作系统上，则会在证书不可用或者未安装时产生错误。如果缺少站点的 SSL 证书，连接会断开，IIS 显示&ldquo;页不可用&rdquo;消息。服务器在事件日志中记录以下警告：&ldquo;解决办法是在相同的证书存储位置重新安装证书并重新启动 IIS。在重新安装证书之后无法重新启动 IIS 会导致不断出现错误日志和断开连接。&rdquo;</p>
<p><a href="http://doc.51windows.net/iismmc/?url=/iismmc/htm/mb_sec_filelevel.htm">http://doc.51windows.net/iismmc/?url=/iismmc/htm/mb_sec_filelevel.htm</a></p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/asp%2Enet">asp.net</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/55337e1ede51d3fd1ad57621.html#comment">查看评论</a>]]></description>
        <pubDate>2009年08月28日 星期五  16:09</pubDate>
        <category><![CDATA[asp.net]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/55337e1ede51d3fd1ad57621.html</guid>
</item>

<item>
        <title><![CDATA[C# WinFrom 实现回车转TAB功能]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/48f04990be71a084a877a40a.html]]></link>
        <description><![CDATA[
		
		<p><span class="t18">方法一：<br>
</span><span class="t18">每个文本框的KeyPress增加：<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if(e.KeyChar = '\r')&nbsp;&nbsp;  SendKeys.Send(&quot;{TAB}&quot;);</span></p>
<p><span class="t18"><br>
方法二：<br>
把Form的KeyPreView设为true，然后在Form的KeyPress中增加下列代码：<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (e.KeyChar == '\r')<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.SelectNextControl(this.ActiveControl, true, true, true, true); </span></p>
<p> </p>
<p> </p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/Csharp">Csharp</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/48f04990be71a084a877a40a.html#comment">查看评论</a>]]></description>
        <pubDate>2009年08月25日 星期二  13:47</pubDate>
        <category><![CDATA[Csharp]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/48f04990be71a084a877a40a.html</guid>
</item>

<item>
        <title><![CDATA[什么是通用网址]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/fed541a7e53c0b9cd043586e.html]]></link>
        <description><![CDATA[
		
		<strong><span class="hong">什么是通用网址?</span><br>
</strong><span class="hong"><font color="#ff0000">★</font></span>答：通用网址是一种新兴的网络名称访问技术，是最快捷、最方便的网络访问标准。网络名称访问技术的演变大致经历了以下过程。最初为便于记忆，网络人员将由二进制&quot;0&quot;、&quot;1&quot;组成的网络地址分割成四段，并采用十进制的方式加以表示，这就是IP地址。随后，科研人员又将纯数字表示的IP地址基础上推出来更加便于记忆的字符型访问标识，即基于IP地址的域名系统。域名系统随即被广泛运用于互联网的各个应用中，例如、电子邮件和FTP等，极大地推动了互联网络的普及。通用网址技术是一种基于域名基础之上，专用于WWW浏览的访问技术。它通过建立通用网址与网站地址URL的对应关系，有效降低了域名体系的复杂性，是实现浏览器访问的一种便捷方式。访问者不用记忆或输入http://、www、.com、.net等复杂冗长的英文域名地址，只要在浏览器网址栏中输入通用网址如企业、产品、品牌的名称或拼音就可以直达目标网站。
<p class="zhengwen"><span class="hong"><strong>怎样使用通用网址？ </strong></span><br>
<span class="hong"><font color="#ff0000">★</font></span>答：通用网址提供了四种访问方式：1、 中文网址：输入企业、产品的全称或简称即可直达目标，如输入&quot;信诺立&quot;，可以直接到达信诺立公司的网站； 2、 英文网址：输入&quot;IBM&quot;即可访问IBM的网站； 3、 拼音网址：输入拼音、拼音字头如&quot;QJD&quot;就可访问的全聚德集团的网站； 4、 数字网址：输入企业的电话号码、股票代码即可直达。</p>
<p class="zhengwen"><span class="hong"><strong>企业已经有了通用域名，还需要通用网址吗？</strong></span><br>
<span class="hong"><font color="#ff0000">★</font></span>答：通用网址是通用域名的伙伴，但两者处在不同层次。企业注册了通用网址后，通用域名将依然存在，并在后台存发挥作用。域名不是品牌正如通信地址不能代表一个企业的形象一样，拥有域名仅仅拥有了网上的地址，通用网址才是企业的网上招牌。通用网址在域名基础上发挥作用，又是更高效、更成熟的访问标准，是对域名的继承和发展。它可以帮助企业解决网络营销和产品推广的困难。---1、对于用户：通用网址更加方便实用； ---2、对于企业：通用网址保护了企业的品牌资源，锁定客户、带来商机； ---3、技术实现：通用网址可以支持智能查询，而域名输入必须精确； ---4、发展趋势：域名日趋繁复，不易记忆，功能有限。通用网址降低了网络的复杂性，是对域名体系的发展而不是否定。</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/%C4%AC%C8%CF%B7%D6%C0%E0">默认分类</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/fed541a7e53c0b9cd043586e.html#comment">查看评论</a>]]></description>
        <pubDate>2009年08月19日 星期三  19:33</pubDate>
        <category><![CDATA[默认分类]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/fed541a7e53c0b9cd043586e.html</guid>
</item>

<item>
        <title><![CDATA[[转]Js操作FCK代码]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/c8e3b01bc43254108718bf3b.html]]></link>
        <description><![CDATA[
		
		<p>function getEditorContents(){<br>
&nbsp;&nbsp;  var oEditor = FCKeditorAPI.GetInstance(&quot;content&quot;);<br>
&nbsp;&nbsp;  alert(oEditor.GetXHTML(true));<br>
}<br>
//向编辑器插入指定代码<br>
function insertHTMLToEditor(codeStr){<br>
&nbsp;&nbsp;  var oEditor = FCKeditorAPI.GetInstance(&quot;content&quot;);<br>
&nbsp;&nbsp;  if (oEditor.EditMode==FCK_EDITMODE_WYSIWYG){<br>
&nbsp;&nbsp;&nbsp;&nbsp;  oEditor.InsertHtml(codeStr);<br>
&nbsp;&nbsp;  }else{<br>
&nbsp;&nbsp;&nbsp;&nbsp;  return false;<br>
&nbsp;&nbsp;  }<br>
}<br>
//统计编辑器中内容的字数<br>
function getLength(){<br>
&nbsp;&nbsp;  var oEditor = FCKeditorAPI.GetInstance(&quot;content&quot;);<br>
&nbsp;&nbsp;  var oDOM = oEditor.EditorDocument;<br>
&nbsp;&nbsp;  var iLength ;<br>
&nbsp;&nbsp;  if(document.all){<br>
&nbsp;&nbsp;&nbsp;&nbsp;  iLength = oDOM.body.innerText.length;<br>
&nbsp;&nbsp;  }else{<br>
&nbsp;&nbsp;&nbsp;&nbsp;  var r = oDOM.createRange();<br>
&nbsp;&nbsp;&nbsp;&nbsp;  r.selectNodeContents(oDOM.body);<br>
&nbsp;&nbsp;&nbsp;&nbsp;  iLength = r.toString().length;<br>
&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;  alert(iLength);<br>
}<br>
//执行指定动作<br>
function ExecuteCommand(commandName){<br>
&nbsp;&nbsp;  var oEditor = FCKeditorAPI.GetInstance(&quot;content&quot;) ;<br>
&nbsp;&nbsp;  oEditor.Commands.GetCommand(commandName).Execute() ;<br>
}<br>
//设置编辑器中内容<br>
function SetContents(codeStr){<br>
&nbsp;&nbsp;  var oEditor = FCKeditorAPI.GetInstance(&quot;content&quot;) ;<br>
&nbsp;&nbsp;  oEditor.SetHTML(codeStr) ;<br>
}</p>
<p>本文来自CSDN博客，出处：<a href="http://blog.csdn.net/impeller/archive/2008/03/05/2152195.aspx">http://blog.csdn.net/impeller/archive/2008/03/05/2152195.aspx</a></p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/Javascript">Javascript</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/c8e3b01bc43254108718bf3b.html#comment">查看评论</a>]]></description>
        <pubDate>2009年08月12日 星期三  10:16</pubDate>
        <category><![CDATA[Javascript]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/c8e3b01bc43254108718bf3b.html</guid>
</item>

<item>
        <title><![CDATA[[转]C#多线程编程（2）：线程的启动]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/c7202c2ebc360f594ec2266d.html]]></link>
        <description><![CDATA[
		
		<p> 继续探索<br>
 上面解决了一个问题，如果在启动线程时需要参数如何解决，如果针对上面的问题继续发掘，比如：在启动线程时不但要指定线程的暂停间隔，还需要指定循环次数（在上面的所有例子中都是执行10次的），这个问题该如何解决呢？<br>
 有两种办法可以解决：<br>
 首先可以继续在ParameterizedThreadStart这里做文章，因为这里可以使用一个Object类型的参数，那么可以通过数组或者一个类来解决（因为它们都是Object的子类）。我在做某个系统时确实采用数组处理过这种情况，这样就要求在线程启动方法中必须清楚知道数组中每个参数的用途，不是太方便。<br>
 这里说说重新定义一个实体类来解决的方法，代码如下。</p>
<p>view plaincopy to clipboardprint?<br>
using System;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Collections.Generic;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Text;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Threading;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  namespace StartThread&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  class MyThreadParameter&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  private int interval;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  private int loopCount;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 循环次数&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public int LoopCount&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  get { return loopCount; }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 线程的暂停间隔&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public int Interval&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  get { return interval; }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 构造函数&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;interval&quot;&gt;线程的暂停间隔&lt;/param&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;loopCount&quot;&gt;循环次数&lt;/param&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public MyThreadParameter(int interval,int loopCount)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.interval = interval;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.loopCount = loopCount;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  class Program&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int interval = 200;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  static void Main(string[] args)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Program p = new Program();&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread parameterThread = new Thread(new ParameterizedThreadStart(p.MyParameterRun));&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Name = &quot;Thread A:&quot;;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  MyThreadParameter paramter = new MyThreadParameter(50, 20);&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Start(paramter);&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 带多个参数的启动方法&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;ms&quot;&gt;方法参数&lt;/param&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public void MyParameterRun(object ms)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  MyThreadParameter parameter = ms as MyThreadParameter;//类型转换&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (parameter != null)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (int i = 0; i &lt; parameter.LoopCount; i++)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(Thread.CurrentThread.Name + &quot;系统当前时间毫秒值：&quot; + DateTime.Now.Millisecond.ToString());&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread.Sleep(parameter.Interval);//让线程暂停&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  }  <br>
using System;<br>
 using System.Collections.Generic;<br>
 using System.Text;<br>
 using System.Threading;<br>
 <br>
 namespace StartThread<br>
 {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  class MyThreadParameter<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  private int interval;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  private int loopCount;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 循环次数<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public int LoopCount<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  get { return loopCount; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 线程的暂停间隔<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public int Interval<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  get { return interval; }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 构造函数<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;interval&quot;&gt;线程的暂停间隔&lt;/param&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;loopCount&quot;&gt;循环次数&lt;/param&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public MyThreadParameter(int interval,int loopCount)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.interval = interval;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.loopCount = loopCount;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;  class Program<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int interval = 200;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  static void Main(string[] args)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Program p = new Program();<br>
 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread parameterThread = new Thread(new ParameterizedThreadStart(p.MyParameterRun));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Name = &quot;Thread A:&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  MyThreadParameter paramter = new MyThreadParameter(50, 20);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Start(paramter);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
  <br>
 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 带多个参数的启动方法<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;ms&quot;&gt;方法参数&lt;/param&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public void MyParameterRun(object ms)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  MyThreadParameter parameter = ms as MyThreadParameter;//类型转换<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (parameter != null)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (int i = 0; i &lt; parameter.LoopCount; i++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(Thread.CurrentThread.Name + &quot;系统当前时间毫秒值：&quot; + DateTime.Now.Millisecond.ToString());<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread.Sleep(parameter.Interval);//让线程暂停<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
 }</p>
<p>第二种方法和上面方法有些相似，也是需要引入外部类，并且将Thread实例放在引入的类中，这种情况适合于在线程中处理的业务逻辑比较复杂的情况。在前不久处理的一个项目中我用过这种情况，它是用来实现双向数据传输的。<br>
 如果实现上面的效果，代码如下：</p>
<p>view plaincopy to clipboardprint?<br>
using System;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Collections.Generic;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Text;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Threading;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  namespace StartThread&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  class MyThreadParameter&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  private int interval;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  private int loopCount;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  private Thread thread;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 构造函数&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;interval&quot;&gt;线程的暂停间隔&lt;/param&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;loopCount&quot;&gt;循环次数&lt;/param&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public MyThreadParameter(int interval,int loopCount)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.interval = interval;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.loopCount = loopCount;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  thread = new Thread(new ThreadStart(Run));&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public void Start()&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (thread != null)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  thread.Start();&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  private void Run()&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (int i = 0; i &lt; loopCount; i++)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(&quot;系统当前时间毫秒值：&quot; + DateTime.Now.Millisecond.ToString());&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread.Sleep(interval);//让线程暂停&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  class Program&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  static void Main(string[] args)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  MyThreadParameter parameterThread = new MyThreadParameter(30, 50);&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Start();&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  }  <br>
using System;<br>
 using System.Collections.Generic;<br>
 using System.Text;<br>
 using System.Threading;<br>
 <br>
 namespace StartThread<br>
 {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  class MyThreadParameter<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  private int interval;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  private int loopCount;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  private Thread thread;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
  /// &lt;summary&gt;<br>
  /// 构造函数<br>
  /// &lt;/summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;interval&quot;&gt;线程的暂停间隔&lt;/param&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;loopCount&quot;&gt;循环次数&lt;/param&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public MyThreadParameter(int interval,int loopCount)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.interval = interval;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  this.loopCount = loopCount;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  thread = new Thread(new ThreadStart(Run));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public void Start()<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  if (thread != null)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  thread.Start();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  private void Run()<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (int i = 0; i &lt; loopCount; i++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(&quot;系统当前时间毫秒值：&quot; + DateTime.Now.Millisecond.ToString());<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread.Sleep(interval);//让线程暂停<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;  class Program<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  static void Main(string[] args)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  MyThreadParameter parameterThread = new MyThreadParameter(30, 50);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Start();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
 <br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
 }</p>
<p>上面的代码的运行效果和前面的代码运行效果类似，只不过是将业务处理代码放在一个单独的类MyThreadParameter中，使得MyThreadParameter看起来也像一个Thread，实际上维护的还是其内部的Thread，在一些大型系统中这样做的好处是便于维护。<br>
 <br>
 总结：在本篇主要讲述如何启动线程的问题，在启动时可能会遇到无需参数、需要多个参数的情况，在这里讲述了如何解决这些问题的思路。在.net类库中虽然存在着庞大的类库，但是并不是总会有合适的类来解决我们所遇到的问题，但是只要肯动脑筋总会想到合适的办法。</p>
<p> </p>
<p><br>
本文来自CSDN博客，出处：<a href="http://blog.csdn.net/zhoufoxcn/archive/2009/08/03/4402999.aspx">http://blog.csdn.net/zhoufoxcn/archive/2009/08/03/4402999.aspx</a></p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/Csharp">Csharp</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/c7202c2ebc360f594ec2266d.html#comment">查看评论</a>]]></description>
        <pubDate>2009年08月04日 星期二  11:24</pubDate>
        <category><![CDATA[Csharp]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/c7202c2ebc360f594ec2266d.html</guid>
</item>

<item>
        <title><![CDATA[[转]C#多线程编程（1）：线程的启动]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/01ee392934fd74f798250a67.html]]></link>
        <description><![CDATA[
		
		<p>在实例化Thread的实例，需要提供一个委托，在实例化这个委托时所用到的参数是线程将来启动时要运行的方法。在.net中提供了两种启动线程的方式，一种是不带参数的启动方式，另一种是带参数的启动的方式。<br>
 不带参数的启动方式<br>
 如果启动参数时无需其它额外的信息，可以使用ThreadStart来实例化Thread，如下面的代码：</p>
<p>view plaincopy to clipboardprint?<br>
using System;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Collections.Generic;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Text;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Threading;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  namespace StartThread&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  class Program&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int interval = 200;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  static void Main(string[] args)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Program p = new Program();&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread nonParameterThread = new Thread(new ThreadStart(p.NonParameterRun));&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  nonParameterThread.Start();&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 不带参数的启动方法&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public void NonParameterRun()&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (int i = 0; i &lt; 10; i++)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(&quot;系统当前时间毫秒值：&quot;+DateTime.Now.Millisecond.ToString());&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread.Sleep(interval);//让线程暂停&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  }  <br>
using System;<br>
 using System.Collections.Generic;<br>
 using System.Text;<br>
 using System.Threading;<br>
 <br>
 namespace StartThread<br>
 {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  class Program<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int interval = 200;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  static void Main(string[] args)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Program p = new Program();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread nonParameterThread = new Thread(new ThreadStart(p.NonParameterRun));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  nonParameterThread.Start();<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 不带参数的启动方法<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public void NonParameterRun()<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (int i = 0; i &lt; 10; i++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(&quot;系统当前时间毫秒值：&quot;+DateTime.Now.Millisecond.ToString());<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread.Sleep(interval);//让线程暂停<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
 }</p>
<p>程序的运行效果我们不用运行也会知道，那就是在循环中将系统当前时间的毫秒部分输出出来，在每次输出之后会将当前线程暂停一下，直到10次之后运行完毕，终止线程的执行。<br>
 在上面的代码中我们是通过定义全局变量的方法来指定线程暂停间隔，按照这种方法，假如要运行10个线程，每个线程的暂停间隔不一样的话，就需要定义10个全局变量，虽然最终不影响系统的运行效果，但是总觉得不是太爽。<br>
 有没有比较简单一点的办法呢？有！那就是使用带参数的启动方法。<br>
 带参数的启动方法<br>
 如果要在实例化线程时要带一些参数，就不能用ThreadStart委托作为构造函数的参数来实例化Thread了，而要ParameterizedThreadStart委托，和ThreadStart一样的是它也是线程启动时要执行的方法，和ThreadStart不同的是，它在实例化时可以用一个带有一个Object参数的方法作为构造函数的参数，而实例化ThreadStart时所用到的方法是没有参数的。<br>
 为什么是Object这样的参数呢？很简单，因为在.net中Object是所有类型的基类，用它可以表示Array(数组）、Interface（接口）、ValueType（值类型，如bool,byte,char,short,int,float,long,double等）、class(类）等.net中的类型。当然，这也意味着如果你要启动一个线程，给它传递一个int类型参数时，必须在启动方法中进行相应的类型转换。<br>
 下面就是一个例子，在启动线程时指定了线程的暂停间隔，代码如下：</p>
<p>view plaincopy to clipboardprint?<br>
using System;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Collections.Generic;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Text;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Threading;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  namespace StartThread&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  class Program&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int interval = 200;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  static void Main(string[] args)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Program p = new Program();&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread parameterThread = new Thread(new ParameterizedThreadStart(p.ParameterRun));&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Name = &quot;Thread A:&quot;;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Start(30);&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 带参数的启动方法&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;ms&quot;&gt;让线程在运行过程中的休眠间隔&lt;/param&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public void ParameterRun(object ms)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int j = 10;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int.TryParse(ms.ToString(), out j);//这里采用了TryParse方法，避免不能转换时出现异常&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (int i = 0; i &lt; 10; i++)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(Thread.CurrentThread.Name+&quot;系统当前时间毫秒值：&quot; + DateTime.Now.Millisecond.ToString());&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread.Sleep(j);//让线程暂停&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  }  <br>
using System;<br>
 using System.Collections.Generic;<br>
 using System.Text;<br>
 using System.Threading;<br>
 <br>
 namespace StartThread<br>
 {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  class Program<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int interval = 200;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  static void Main(string[] args)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Program p = new Program();<br>
 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread parameterThread = new Thread(new ParameterizedThreadStart(p.ParameterRun));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Name = &quot;Thread A:&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Start(30);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 带参数的启动方法<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;ms&quot;&gt;让线程在运行过程中的休眠间隔&lt;/param&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public void ParameterRun(object ms)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int j = 10;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int.TryParse(ms.ToString(), out j);//这里采用了TryParse方法，避免不能转换时出现异常<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (int i = 0; i &lt; 10; i++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(Thread.CurrentThread.Name+&quot;系统当前时间毫秒值：&quot; + DateTime.Now.Millisecond.ToString());<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread.Sleep(j);//让线程暂停<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
 }</p>
<p>在这个方法里，我们在启动线程时顺便指定了线程的暂停间隔，也就是这句：<br>
 parameterThread.Start(30);<br>
 线程启动时运行的方法是public void ParameterRun(object ms)，这个值为30的int类型变量被装箱成object，所以在方法中还需要将它转换成int类型，这个可以通过拆箱或者其它办法解决。<br>
 假如我们要启动两个线程，每个线程的暂停间隔不一样，启动代码如下：</p>
<p>view plaincopy to clipboardprint?<br>
using System;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Collections.Generic;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Text;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  using System.Threading;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  namespace StartThread&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  class Program&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int interval = 200;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  static void Main(string[] args)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Program p = new Program();&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread parameterThread = new Thread(new ParameterizedThreadStart(p.ParameterRun));&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Name = &quot;Thread A:&quot;;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Start(30);&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //启动第二个线程&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread = new Thread(new ParameterizedThreadStart(p.ParameterRun));&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Name = &quot;Thread B:&quot;;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Start(60);&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 带参数的启动方法&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;ms&quot;&gt;让线程在运行过程中的休眠间隔&lt;/param&gt;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public void ParameterRun(object ms)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int j = 10;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int.TryParse(ms.ToString(), out j);//这里采用了TryParse方法，避免不能转换时出现异常&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (int i = 0; i &lt; 10; i++)&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(Thread.CurrentThread.Name+&quot;系统当前时间毫秒值：&quot; + DateTime.Now.Millisecond.ToString());&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread.Sleep(j);//让线程暂停&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;  }  <br>
using System;<br>
 using System.Collections.Generic;<br>
 using System.Text;<br>
 using System.Threading;<br>
 <br>
 namespace StartThread<br>
 {<br>
&nbsp;&nbsp;&nbsp;&nbsp;  class Program<br>
&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int interval = 200;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  static void Main(string[] args)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Program p = new Program();<br>
 <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread parameterThread = new Thread(new ParameterizedThreadStart(p.ParameterRun));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Name = &quot;Thread A:&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Start(30);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //启动第二个线程<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread = new Thread(new ParameterizedThreadStart(p.ParameterRun));<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Name = &quot;Thread B:&quot;;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  parameterThread.Start(60);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;  <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// 带参数的启动方法<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;/summary&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  /// &lt;param name=&quot;ms&quot;&gt;让线程在运行过程中的休眠间隔&lt;/param&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  public void ParameterRun(object ms)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int j = 10;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int.TryParse(ms.ToString(), out j);//这里采用了TryParse方法，避免不能转换时出现异常<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  for (int i = 0; i &lt; 10; i++)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Console.WriteLine(Thread.CurrentThread.Name+&quot;系统当前时间毫秒值：&quot; + DateTime.Now.Millisecond.ToString());<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Thread.Sleep(j);//让线程暂停<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
&nbsp;&nbsp;&nbsp;&nbsp;  }<br>
 }</p>
<p>对上面的代码做一点说明，就是线程启动之后，线程的实例不必再存在，例如在上面的代码中我用的是同一个实例实例化了两个线程，并且这两个线程运行很正常。<br>
 </p>
<p>本文来自CSDN博客，出处：<a href="http://blog.csdn.net/zhoufoxcn/archive/2009/08/03/4402999.aspx">http://blog.csdn.net/zhoufoxcn/archive/2009/08/03/4402999.aspx</a></p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/Csharp">Csharp</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/01ee392934fd74f798250a67.html#comment">查看评论</a>]]></description>
        <pubDate>2009年08月04日 星期二  11:18</pubDate>
        <category><![CDATA[Csharp]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/01ee392934fd74f798250a67.html</guid>
</item>

<item>
        <title><![CDATA[[转] 总结JS打印]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/58f04f08dfef999c0b7b8281.html]]></link>
        <description><![CDATA[
		
		<table class="FCK__ShowTableBorders" style="table-layout: fixed">
    <tbody>
        <tr>
            <td>
            <div class="cnt" >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  最近做项目用到订单打印，看到一个不错的文章，转来收藏一下，呵呵<br>
            <br>
            《转》http://ltc603.javaeye.com/blog/123191<br>
            <br>
            对JS的打印方法总结一下，方便日后查阅。<br>
            <br>
            一．用JS自带函数打印<br>
            <br>
            直接调用<br>
            Java代码 复制代码<br>
            <br>
            &nbsp;&nbsp;  1. &lt;a href=&quot;javascript:window.print();&quot;&gt;打印&lt;/a&gt; <br>
            <br>
            &lt;a href=&quot;javascript:window.print();&quot;&gt;打印&lt;/a&gt;<br>
            <br>
            <br>
            <br>
            二．IEWebBrowser组件<br>
            <br>
            介绍<br>
            <br>
            http://support.microsoft.com/default.aspx?scid=kb%3BEN-US%3BQ267240#top<br>
            http://support.microsoft.com/kb/q247671/#appliesto<br>
            <br>
            Java代码 复制代码<br>
            <br>
            &nbsp;&nbsp;  1. &lt;OBJECT classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 id=WebBrowser width=0&gt;&lt;/OBJECT&gt;&nbsp;&nbsp;  <br>
            &nbsp;&nbsp;  2. &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(1,1) type=button value=打开&gt; <br>
            &nbsp;&nbsp;  3. &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(2,1) type=button value=关闭所有&gt; <br>
            &nbsp;&nbsp;  4. &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(4,1) type=button value=另存为&gt;&nbsp;&nbsp;  <br>
            &nbsp;&nbsp;  5. &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(6,1) type=button value=打印&gt; <br>
            &nbsp;&nbsp;  6. &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(6,6) type=button value=直接打印&gt; <br>
            &nbsp;&nbsp;  7. &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(7,1) type=button value=打印预览&gt; <br>
            &nbsp;&nbsp;  8. &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(8,1) type=button value=页面设置&gt; <br>
            &nbsp;&nbsp;  9. &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(10,1) type=button value=属性&gt; <br>
            10. &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(17,1) type=button value=全选&gt; <br>
            11. &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(22,1) type=button value=刷新&gt; <br>
            12. &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(45,1) type=button value=关闭&gt; <br>
            <br>
            &lt;OBJECT classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 id=WebBrowser width=0&gt;&lt;/OBJECT&gt; <br>
            &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(1,1) type=button value=打开&gt;<br>
            &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(2,1) type=button value=关闭所有&gt;<br>
            &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(4,1) type=button value=另存为&gt; <br>
            &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(6,1) type=button value=打印&gt;<br>
            &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(6,6) type=button value=直接打印&gt;<br>
            &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(7,1) type=button value=打印预览&gt;<br>
            &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(8,1) type=button value=页面设置&gt;<br>
            &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(10,1) type=button value=属性&gt;<br>
            &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(17,1) type=button value=全选&gt;<br>
            &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(22,1) type=button value=刷新&gt;<br>
            &lt;input name=Button onClick=document.all.WebBrowser.ExecWB(45,1) type=button value=关闭&gt;<br>
            <br>
            <br>
            <br>
            三．使用ScriptX.cab控件<br>
            <br>
            1．下载ScriptX.cab控件<br>
            <br>
            官网http://www.meadroid.com/scriptx/index.asp<br>
            <br>
            2．使用object元素，修改codebase，classid的值<br>
            <br>
            这里调用控件ScriptX.cab<br>
            Java代码 复制代码<br>
            <br>
            &nbsp;&nbsp;  1. &lt;OBJECT id=&quot;factory&quot; style=&quot;DISPLAY: none&quot; codeBase=&quot;${rootUrl}js/smsx.cab#VVersion=6,3,435,20&quot; classid=&quot;clsid:1663ed61-23eb-11d2-b92f-008048fdd814&quot; viewastext&gt;&lt;/OBJECT&gt; <br>
            <br>
            &lt;OBJECT id=&quot;factory&quot; style=&quot;DISPLAY: none&quot; codeBase=&quot;${rootUrl}js/smsx.cab#VVersion=6,3,435,20&quot; classid=&quot;clsid:1663ed61-23eb-11d2-b92f-008048fdd814&quot; viewastext&gt;&lt;/OBJECT&gt;<br>
            <br>
            <br>
            <br>
            这段代码用来加载cab文件，clsid和codebase必须要和你下载的cab中的信息对应，否则组件会加载错误，这两项其实不难找，只要你用winrar打开你下载的cab文件，然后找到扩展名是.inf的文件，然后打开之，就能看到了。<br>
            <br>
            3．调用控件脚本<br>
            <br>
            Print.js文件<br>
            Java代码 复制代码<br>
            <br>
            &nbsp;&nbsp;  1. function setPrintBase(headerText,footerText,rootUrl) { <br>
            &nbsp;&nbsp;  2.&nbsp;&nbsp;  <br>
            &nbsp;&nbsp;  3.&nbsp;&nbsp;&nbsp;&nbsp;  // -- advanced features ，未曾使用过，有待确认。 <br>
            &nbsp;&nbsp;  4.&nbsp;&nbsp;  <br>
            &nbsp;&nbsp;  5.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.printing.SetMarginMeasure(2); // measure margins in inches <br>
            &nbsp;&nbsp;  6.&nbsp;&nbsp;  <br>
            &nbsp;&nbsp;  7.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.SetPageRange(false, 1, 3);// need pages from 1 to 3 <br>
            &nbsp;&nbsp;  8.&nbsp;&nbsp;  <br>
            &nbsp;&nbsp;  9.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.printing.printer = &quot;HP DeskJet 870C&quot;; <br>
            10.&nbsp;&nbsp;  <br>
            11.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.printing.copies = 2; <br>
            12.&nbsp;&nbsp;  <br>
            13.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.printing.collate = true; <br>
            14.&nbsp;&nbsp;  <br>
            15.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.printing.paperSize = &quot;A4&quot;; <br>
            16.&nbsp;&nbsp;  <br>
            17.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.printing.paperSource = &quot;Manual feed&quot; <br>
            18.&nbsp;&nbsp;  <br>
            19.&nbsp;&nbsp;&nbsp;&nbsp;  var header = (headerText==null||headerText==&quot;&quot;)?'默认页眉':headerText; <br>
            20.&nbsp;&nbsp;  <br>
            21.&nbsp;&nbsp;&nbsp;&nbsp;  var footer = (footerText==null||footerText==&quot;&quot;)?'默认页角':footerText; <br>
            22.&nbsp;&nbsp;  <br>
            23.&nbsp;&nbsp;  factory.printing.header = &quot;&amp;b&quot;+header+&quot;&amp;b&quot; ; <br>
            24.&nbsp;&nbsp;  <br>
            25.&nbsp;&nbsp;  factory.printing.footer = &quot;&amp;b&quot;+footer; <br>
            26.&nbsp;&nbsp;  <br>
            27.&nbsp;&nbsp;  factory.printing.portrait = true; <br>
            28.&nbsp;&nbsp;  <br>
            29.&nbsp;&nbsp;  factory.printing.leftMargin =10.00; <br>
            30.&nbsp;&nbsp;  <br>
            31.&nbsp;&nbsp;  factory.printing.topMargin =10.00; <br>
            32.&nbsp;&nbsp;  <br>
            33.&nbsp;&nbsp;  factory.printing.rightMargin =10.00; <br>
            34.&nbsp;&nbsp;  <br>
            35.&nbsp;&nbsp;  factory.printing.bottomMargin =10.00; <br>
            36.&nbsp;&nbsp;  <br>
            37. } <br>
            <br>
            function setPrintBase(headerText,footerText,rootUrl) {<br>
            <br>
            &nbsp;&nbsp;&nbsp;  // -- advanced features ，未曾使用过，有待确认。<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.printing.SetMarginMeasure(2); // measure margins in inches<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.SetPageRange(false, 1, 3);// need pages from 1 to 3<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.printing.printer = &quot;HP DeskJet 870C&quot;;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.printing.copies = 2;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.printing.collate = true;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.printing.paperSize = &quot;A4&quot;;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  //factory.printing.paperSource = &quot;Manual feed&quot;<br>
            <br>
            &nbsp;&nbsp;&nbsp;  var header = (headerText==null||headerText==&quot;&quot;)?'默认页眉':headerText;<br>
            <br>
            &nbsp;&nbsp;&nbsp;  var footer = (footerText==null||footerText==&quot;&quot;)?'默认页角':footerText;<br>
            <br>
            factory.printing.header = &quot;&amp;b&quot;+header+&quot;&amp;b&quot; ;<br>
            <br>
            factory.printing.footer = &quot;&amp;b&quot;+footer;<br>
            <br>
            factory.printing.portrait = true;<br>
            <br>
            factory.printing.leftMargin =10.00;<br>
            <br>
            factory.printing.topMargin =10.00;<br>
            <br>
            factory.printing.rightMargin =10.00;<br>
            <br>
            factory.printing.bottomMargin =10.00;<br>
            <br>
            }<br>
            <br>
            <br>
            <br>
            <br>
            例子<br>
            Java代码 复制代码<br>
            <br>
            &nbsp;&nbsp;  1. &lt;%@ page contentType=&quot;text/html;charset=GBK&quot;%&gt; <br>
            &nbsp;&nbsp;  2.&nbsp;&nbsp;  <br>
            &nbsp;&nbsp;  3. &lt;html&gt; <br>
            &nbsp;&nbsp;  4. &lt;head&gt; <br>
            &nbsp;&nbsp;  5. &lt;meta http-equiv=&quot;imagetoolbar&quot; content=&quot;no&quot;&gt; <br>
            &nbsp;&nbsp;  6. &lt;script language=&quot;javascript&quot; src=&quot;print.js&quot;&gt;&lt;/script&gt; <br>
            &nbsp;&nbsp;  7. &lt;style media=&quot;print&quot;&gt; <br>
            &nbsp;&nbsp;  8. .Noprint&nbsp;&nbsp;  {DISPLAY:&nbsp;&nbsp;  none;} <br>
            &nbsp;&nbsp;  9. &lt;/style&gt; <br>
            10. &lt;title&gt;打印测试&lt;/title&gt; <br>
            11. &lt;/head&gt; <br>
            12. &lt;OBJECT id=&quot;factory&quot; style=&quot;DISPLAY: none&quot; codeBase=&quot;smsx.cab#VVersion=6,3,435,20&quot; classid=&quot;clsid:1663ed61-23eb-11d2-b92f-008048fdd814&quot; viewastext&gt;&lt;/OBJECT&gt; <br>
            13.&nbsp;&nbsp;  <br>
            14. &lt;script defer&gt; <br>
            15. function window.onload() {&nbsp;&nbsp;&nbsp;&nbsp;  <br>
            16. setPrintBase('页眉','页脚'); <br>
            17. } <br>
            18. &lt;/script&gt; <br>
            19. &lt;body topmargin=&quot;0&quot; leftmargin=&quot;0&quot; rightmargin=&quot;0&quot; bottommargin=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot;&gt; <br>
            20. &lt;center class=&quot;Noprint&quot;&gt; <br>
            21. &lt;input type=button value=&quot;打印&quot; onclick=&quot;factory.printing.Print(true)&quot;&gt;&nbsp;&nbsp;  <br>
            22. &lt;input type=button value=&quot;页面设置&quot; onclick=&quot;factory.printing.PageSetup()&quot;&gt;&nbsp;&nbsp;  <br>
            23. &lt;input type=button value=&quot;打印预览&quot; onclick=&quot;factory.printing.Preview()&quot;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
            24. &lt;input type=&quot;button&quot; value=&quot;关闭&quot; onclick=&quot;window.close();&quot;&gt; <br>
            25. &lt;/center&gt; <br>
            26.&nbsp;&nbsp;&nbsp;  &lt;center&gt; <br>
            27.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &lt;table width=&quot;100%&quot; border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt; <br>
            28.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &lt;tr&gt;&lt;td align=&quot;center&quot;&gt;&lt;b&gt;内容&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt; <br>
            29.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &lt;/table&gt; <br>
            30.&nbsp;&nbsp;&nbsp;&nbsp;  &lt;/center&gt; <br>
            31. &lt;/body&gt; <br>
            32. &lt;/html&gt; <br>
            <br>
            &lt;%@ page contentType=&quot;text/html;charset=GBK&quot;%&gt;<br>
            <br>
            &lt;html&gt;<br>
            &lt;head&gt;<br>
            &lt;meta http-equiv=&quot;imagetoolbar&quot; content=&quot;no&quot;&gt;<br>
            &lt;script language=&quot;javascript&quot; src=&quot;print.js&quot;&gt;&lt;/script&gt;<br>
            &lt;style media=&quot;print&quot;&gt;<br>
            .Noprint&nbsp;&nbsp;  {DISPLAY:&nbsp;&nbsp;  none;}<br>
            &lt;/style&gt;<br>
            &lt;title&gt;打印测试&lt;/title&gt;<br>
            &lt;/head&gt;<br>
            &lt;OBJECT id=&quot;factory&quot; style=&quot;DISPLAY: none&quot; codeBase=&quot;smsx.cab#VVersion=6,3,435,20&quot; classid=&quot;clsid:1663ed61-23eb-11d2-b92f-008048fdd814&quot; viewastext&gt;&lt;/OBJECT&gt;<br>
            <br>
            &lt;script defer&gt;<br>
            function window.onload() {&nbsp;&nbsp;  <br>
            setPrintBase('页眉','页脚');<br>
            }<br>
            &lt;/script&gt;<br>
            &lt;body topmargin=&quot;0&quot; leftmargin=&quot;0&quot; rightmargin=&quot;0&quot; bottommargin=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot;&gt;<br>
            &lt;center class=&quot;Noprint&quot;&gt;<br>
            &lt;input type=button value=&quot;打印&quot; onclick=&quot;factory.printing.Print(true)&quot;&gt; <br>
            &lt;input type=button value=&quot;页面设置&quot; onclick=&quot;factory.printing.PageSetup()&quot;&gt; <br>
            &lt;input type=button value=&quot;打印预览&quot; onclick=&quot;factory.printing.Preview()&quot;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <br>
            &lt;input type=&quot;button&quot; value=&quot;关闭&quot; onclick=&quot;window.close();&quot;&gt;<br>
            &lt;/center&gt;<br>
            &nbsp;&nbsp;  &lt;center&gt;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &lt;table width=&quot;100%&quot; border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &lt;tr&gt;&lt;td align=&quot;center&quot;&gt;&lt;b&gt;内容&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &lt;/table&gt;<br>
            &nbsp;&nbsp;&nbsp;  &lt;/center&gt;<br>
            &lt;/body&gt;<br>
            &lt;/html&gt;<br>
            <br>
            <br>
            <br>
            四．对比<br>
            <br>
            1．Window.print调用方便，但功能简单<br>
            <br>
            2．功能更强大，但使用IEWebBrowser有时会报JS没有权限的错误。<br>
            <br>
            3．ScriptX控件功能也比较强大，目前在使用这种方式。<br>
            <br>
            这里的也不错啊，有打印到 word的和excel<br>
            <br>
            http://hi.baidu.com/afei0211/blog/item/20523955ca8bebc2b745ae98.html<br>
            <br>
            http://hi.baidu.com/hongz1125/blog/item/0152bcfd84ce1e1008244d5c.html<br>
            <br>
            .NET环境下的<br>
            http://blog.csdn.net/flygoldfish/archive/2004/08/17/77208.aspx</div>
            </td>
        </tr>
    </tbody>
</table> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/asp%2Enet">asp.net</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/58f04f08dfef999c0b7b8281.html#comment">查看评论</a>]]></description>
        <pubDate>2009年07月30日 星期四  10:29</pubDate>
        <category><![CDATA[asp.net]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/58f04f08dfef999c0b7b8281.html</guid>
</item>

<item>
        <title><![CDATA[前后反差，有意思！]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/092dd200e35c4c18738b659c.html]]></link>
        <description><![CDATA[
		
		<p>进入公司前</p>
<p>老板：万分欢迎，没有你我们的公司肯定大不一样！&nbsp;&nbsp;  <br>
职员：如果工作太累，搞不好我会辞职的&nbsp;&nbsp;  <br>
老板：放心，我不会让这样的事情发生的！&nbsp;&nbsp;  <br>
职员：我双休日可以休息吗？&nbsp;&nbsp;  <br>
老板：当然了！这是底线！&nbsp;&nbsp;  <br>
职员：平时会天天加班到凌晨吗？&nbsp;&nbsp;  <br>
老板：不可能，谁告诉你的？&nbsp;&nbsp;  <br>
职员：有餐费补贴吗？&nbsp;&nbsp;  <br>
老板：还用说吗，绝对比同行都高！&nbsp;&nbsp;  <br>
职员：有没有工作猝死的风险？&nbsp;&nbsp;  <br>
老板：不会！你怎么会有这种念头？&nbsp;&nbsp;  <br>
职员：公司会定期组织旅游吗？&nbsp;&nbsp;  <br>
老板：这是我们的明文规定！&nbsp;&nbsp;  <br>
职员：那我需要准时上班吗？&nbsp;&nbsp;  <br>
老板：不，看情况吧&nbsp;&nbsp;  <br>
职员：工资呢？会准时发吗？&nbsp;&nbsp;  <br>
老板：一向如此！&nbsp;&nbsp;  <br>
职员：事情全是新员工做吗？&nbsp;&nbsp;  <br>
老板：怎么可能，你上头还有很多资深同事！&nbsp;&nbsp;  <br>
职员：如果领导职位有空缺，我可以参与竞争吗啊？&nbsp;&nbsp;  <br>
老板：毫无疑问，这是我们公司赖以生存的机制！&nbsp;&nbsp;  <br>
职员：你不会是在骗我吧？ <br>
  <br>
进入公司后看真实的一幕（从后往前读）</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/%D0%DD%CF%D0%B8%E3%D0%A6">休闲搞笑</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/092dd200e35c4c18738b659c.html#comment">查看评论</a>]]></description>
        <pubDate>2009年07月29日 星期三  11:29</pubDate>
        <category><![CDATA[休闲搞笑]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/092dd200e35c4c18738b659c.html</guid>
</item>

<item>
        <title><![CDATA[效果小记，备忘！！]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/fbb7f11f576b196af724e43a.html]]></link>
        <description><![CDATA[
		
		总看到这个效果，但总是忽略是怎么实现的，今天在163的邮箱里的到再次看到效果，于是记下来，以备不时之需！
<p align="center" forimg="1"><img class="blogimg" border="0" small="0" src="http://hiphotos.baidu.com/zck98530/pic/item/7da597eecf3056012cf5342d.jpg"></p>
<p align="left" forimg="1">HTML代码：<br>
&lt;select class=&quot;combo_address&quot; name=&quot;dest&quot;&gt;<br>
&lt;optgroup label=&quot;=== 请选择文件夹 ===&quot;&gt;<br>
&lt;option value=&quot;7152116&quot; selected&gt;/&lt;/option&gt;<br>
&lt;option value=&quot;7152117&quot;&gt;/我的文档/&lt;/option&gt;<br>
&lt;option value=&quot;7152122&quot;&gt;/我的文档/新建文件夹/&lt;/option&gt;<br>
&lt;option value=&quot;7152123&quot;&gt;/我的文档/新建文件夹/001/&lt;/option&gt;<br>
&lt;option value=&quot;7152124&quot;&gt;/我的文档/新建文件夹/001/002/&lt;/option&gt;<br>
&lt;option value=&quot;7152118&quot;&gt;/我的图片/&lt;/option&gt;<br>
&lt;option value=&quot;7152119&quot;&gt;/我的音乐/&lt;/option&gt;<br>
&lt;option value=&quot;7152120&quot;&gt;/我的多媒体/&lt;/option&gt;<br>
&lt;option value=&quot;7152121&quot;&gt;/我的软件/&lt;/option&gt;<br>
&lt;/optgroup&gt;<br>
&lt;optgroup label=&quot;=== 请选择文件夹 ===&quot;&gt;<br>
&lt;option value=&quot;7152116&quot; selected&gt;/&lt;/option&gt;<br>
&lt;/optgroup&gt;<br>
&lt;/select&gt;</p> 
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/asp%2Enet">asp.net</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/fbb7f11f576b196af724e43a.html#comment">查看评论</a>]]></description>
        <pubDate>2009年07月24日 星期五  08:31</pubDate>
        <category><![CDATA[asp.net]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/fbb7f11f576b196af724e43a.html</guid>
</item>

<item>
        <title><![CDATA[网众下一些实用的命令]]></title>
        <link><![CDATA[http://hi.baidu.com/zck98530/blog/item/a40ab1fbbabd392b4e4aeac3.html]]></link>
        <description><![CDATA[
		
		命令：<br>
cp 拷贝 rm 删除 cd进入  &nbsp;&nbsp;&nbsp; ls查看 nedit编辑 cat打开  &nbsp;&nbsp;&nbsp; sh执行  &nbsp;&nbsp;&nbsp; mv改名&nbsp;&nbsp; top 类似于WIN下的任务管理器<br>
dmesg加载启动信息 lspci查看PCI信息 pstree进程 w显示当前负载&nbsp;&nbsp; hdparm -Tt&nbsp;&nbsp; /dev/***   检测某盘的速度<br>
fdisk -l 查看磁盘信息  &nbsp;&nbsp;&nbsp; killall 杀死 df -h 查看磁盘空间 netconfig 网卡配置<br>
ifconfig 显示IP <br>
reboot 重启 mount 挂载信息 mdadm -D /dev/md0 检查软阵列 nxpver 版本<br>
mke2fs -j /dev/sda3格式化回写分区  &nbsp;&nbsp;&nbsp; reboot 重启  &nbsp;&nbsp;&nbsp; poweroff 关机<br>
<br>
<br>
手动加载29320驱动<br>
aic79XX  &nbsp;&nbsp;&nbsp; 自已添加 /etc/rc.d 目录编辑 rc.modules文件，最后一行加<br>
/sbin/modprobe aic79xx <br>
手动加载LSI1030驱动<br>
nedit /etc/rc.d/rc.modules<br>
最后一行加上/sbin/modprobe mptscsih(ft3xx TX4000阵列)<br>
或挂载modprobe mptscsih。 cd /etc/rc.d   <br>
ech0 /sbin/modprobe mptscsih &gt;&gt;rc.modules<br>
<br>
网众连接：<br>
export DISPLAY=60.63.246.96:1 Xterm &amp;<br>
<br>
端口：<br>
AUTO Y 21 TO 21 192.168.1.251<br>
网众：5901<br>
<br>
<br>
优化硬盘读写参数：<br>
elvtune -r 1024 -w 2048 /dev/sda /dev/sdb<br>
<br>
软阵列设置<br>
(注意网众软阵列工作站母盘阵列卷大小一定为64K)<br>
/usr/lib/netzone/mdconfig<br>
./mdconfig（/sda3---sdb 工作站回写  &nbsp;&nbsp;&nbsp; /Sdc--sdb工作站母盘）<br>
或/usr/lib/netzone/mkraid<br>
nzsyscfg配置命令<br>
<br>
<br>
XP安装客户端无法启动<br>
HKEY_LOCAL_MACHINE\SYSTEM\CurrentCcontrolSet\Control\class\&lt;4D36E972-E325-11CE-BFC1-08002BE10318&gt;修改upperfilter，把NXP去掉。<br>
<br>
客户端版本：<br>
HKEY_LOCAL_MACHINE\SOFTWARE\NETZONESOFT\NXD XP\Option<br>
CFG  &nbsp;&nbsp;&nbsp; 工作站对应的配置只读<br>
DISK  &nbsp;&nbsp;&nbsp; 磁盘只读<br>
super  &nbsp;&nbsp;&nbsp; 超级工作站只读<br>
severIP nxp 服务端<br>
nxpclient 客户端<br>
<br>
页面文件大小：<br>
HKEY_LOCAL_MACHINE\SYSTEM\CurrentCcontrolSet\SEVVICES\nxdinit\<br>
pagefile  &nbsp;&nbsp;&nbsp; c:\pagefile.sys 512 512<br>
<br>
<br>
故障:<br>
一.工作站有一台工作站在XP滚动条不断滚动?<br>
首先把这台工作站的IP地址换一下,一般是IP地址冲突.<br>
如果有太多的或全部的的话,有可能更网众服务端有问题,请更换服务端.<br>
<br>
<br>
二.服务器一切正常,所有工作无法启动,无法引导?<br>
首先:打开nxp管理器看看有没有什么报错,如果没有一切正常,能看到工作站记录.<br>
检查服务器网络是否连接正常,打开网站看服务器络是否能打开网站.<br>
重启一下nxp服务(打开终端nxp restart)<br>
<br>
三.服务器很卡,工作站也很卡?<br>
首先检查一下,服务器负载(打开终端:w----看第一个三位数是否大于5,如果大于5说明服务器负载很重,低下5说明服务器负载正常).<br>
检查一下,服务器是否是硬盘是否有报错(打开终端:dmesg-----看看是否有硬盘错误信息.<br>
打开终端:cat /opt/netzone/nxp/syslog.txt----看看有没有什么特殊的报错)<br>
最后,看一下服务端和客户端的使用.更换一个好的服务端和客户端.<br>
<br>
<br>
四.服务器死机?(服务器Caps Lock灯和Scroll Lock灯闪烁)<br>
最常见的服务器内存出问题,更换内存测试.<br>
其次检查硬盘是否正常,如没有报错.更换电源测试.<br>
<br>
<br>
五.打开NXP管理器报错,报配置不完整?<br>
查看磁盘是否满了.用df -h 查看磁盘空间,如果满了<br>
1. 先把挂载的分区umount<br>
一般需要先停止服务，然后执行umount /mnt<br>
如果无法卸载，需要重新启动一下服务器<br>
2. 格式化回写分区<br>
mke2fs -j /dev/sda3<br>
3. 重新挂载回写分区<br>
mount /mnt /dev/sda3 <br>
进入终端：<br>
cd /opt/netzone/nxp/sysback<br>
cp 20060305.CFG ../SYSINFO.CFG<br>
nxp restart从启一下nxp服务<br>
<br>
如果没满,新建一个磁盘,把所有工作站选中,编辑一下.<br>
nxp restart从启一下nxp服务<br>
<br>
加载启动项：<br>
echo nxp restart &gt;&gt; /etc/rc.d/rc.local  
		
		<br/><b>类别：</b><a href="http://hi.baidu.com/zck98530/blog/category/%B2%D9%D7%F7%CF%B5%CD%B3">操作系统</a>&nbsp;<a href="http://hi.baidu.com/zck98530/blog/item/a40ab1fbbabd392b4e4aeac3.html#comment">查看评论</a>]]></description>
        <pubDate>2009年07月14日 星期二  09:25</pubDate>
        <category><![CDATA[操作系统]]></category>
        <author><![CDATA[zck98530]]></author>
		<guid>http://hi.baidu.com/zck98530/blog/item/a40ab1fbbabd392b4e4aeac3.html</guid>
</item>


</channel>
</rss>