<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns="http://purl.org/rss/1.0/">
<channel rdf:about="https://www.rickw.cn/">
<title>Rick 's BLOG</title>
<link>https://www.rickw.cn/</link>
<description>Rick 's BLOG</description>
<dc:language>zh-cn</dc:language>
<dc:creator>redcheek@gmail.com</dc:creator>
<items>
<rdf:Seq>
<item rdf:about="https://www.rickw.cn/blogview/339">
<title><![CDATA[C#实现WebApi接口数据传输加密方案]]></title>
	
<description><![CDATA[在项目开发中我们经常会调用接口或者实现一套webapi接口；<br />
如果项目要上线到公网中，那么我们就需要考虑安全问题；<br />
即便是在内网使用，安全问题也同样不能忽视。<br />
如果没有一套安全方案，那么我们的服务很有可能会被攻击。<br />
<br />]]></description>
<content:encoded><![CDATA[在项目开发中我们经常会调用接口或者实现一套webapi接口；<br />
如果项目要上线到公网中，那么我们就需要考虑安全问题；<br />
即便是在内网使用，安全问题也同样不能忽视。<br />
如果没有一套安全方案，那么我们的服务很有可能会被攻击。<br />
<br />
安全方案主要有加签名进行数据效验、传输数据加密等。<br />
<br />
<h2>1、加签SHA256</h2><br />
<div class="txt_main">public static string GetSHA256Hash(string input)<br />
{<br />
	using&nbsp;(SHA256 sha256Hash&nbsp;= SHA256.Create())<br />
	{<br />
		byte[]&nbsp;bytes&nbsp;=&nbsp;sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(input));<br />
		StringBuilder builder&nbsp;= new StringBuilder();<br />
		for (int&nbsp;i&nbsp;= 0;&nbsp;i&nbsp;&lt;&nbsp;bytes.Length;&nbsp;i++)<br />
		{<br />
			builder.Append(bytes[i].ToString("x2"));<br />
		}<br />
		return builder.ToString();<br />
	}<br />
}<br />
</div><br />
<br />
<h2>2、RSA加密/解密</h2><br />
<div class="txt_main">private&nbsp;readonly&nbsp;RSA&nbsp;_privateKeyRsaProvider;<br />
private&nbsp;readonly&nbsp;RSA&nbsp;_publicKeyRsaProvider;<br />
private&nbsp;readonly&nbsp;Encoding&nbsp;_encoding;<br />
/// &lt;param&nbsp;name="encoding"&gt;编码类型&lt;/param&gt;<br />
/// &lt;param&nbsp;name="privateKey"&gt;私钥&lt;/param&gt;<br />
/// &lt;param&nbsp;name="publicKey"&gt;公钥&lt;/param&gt;<br />
public&nbsp;RSAHelper(Encoding&nbsp;encoding,&nbsp;string&nbsp;privateKey,&nbsp;string&nbsp;publicKey&nbsp;=&nbsp;null)<br />
{<br />
	_encoding&nbsp;=&nbsp;encoding;<br />
	if&nbsp;(!string.IsNullOrEmpty(privateKey))<br />
	{<br />
		_privateKeyRsaProvider&nbsp;=&nbsp;CreateRsaProviderFromPrivateKey(privateKey);<br />
	}<br />
	if&nbsp;(!string.IsNullOrEmpty(publicKey))<br />
	{<br />
		_publicKeyRsaProvider&nbsp;=&nbsp;CreateRsaProviderFromPublicKey(publicKey);<br />
	}<br />
}<br />
//解密<br />
public&nbsp;string&nbsp;Decrypt(string&nbsp;cipherText)<br />
{<br />
	if&nbsp;(_privateKeyRsaProvider&nbsp;==&nbsp;null)<br />
	{<br />
		throw&nbsp;new&nbsp;Exception("_privateKeyRsaProvider&nbsp;is&nbsp;null");<br />
	}<br />
	return&nbsp;Encoding.UTF8.GetString(_privateKeyRsaProvider.Decrypt(Convert.FromBase64String(cipherText),&nbsp;RSAEncryptionPadding.Pkcs1));<br />
}<br />
//加密<br />
public&nbsp;string&nbsp;Encrypt(string&nbsp;text)<br />
{<br />
	if&nbsp;(_publicKeyRsaProvider&nbsp;==&nbsp;null)<br />
	{<br />
		throw&nbsp;new&nbsp;Exception("_publicKeyRsaProvider&nbsp;is&nbsp;null");<br />
	}<br />
	return&nbsp;Convert.ToBase64String(_publicKeyRsaProvider.Encrypt(Encoding.UTF8.GetBytes(text),&nbsp;RSAEncryptionPadding.Pkcs1));<br />
}<br />
</div><br />
<br />
<h2>3、AES加密/解密</h2><br />
<div class="txt_main">/// &lt;summary&gt;<br />
///&nbsp;加密不带偏移量<br />
/// &lt;/summary&gt;<br />
/// &lt;param&nbsp;name="input"&gt;&lt;/param&gt;<br />
/// &lt;param&nbsp;name="key"&gt;秘钥&lt;/param&gt;<br />
/// &lt;returns&gt;&lt;/returns&gt;<br />
public&nbsp;static&nbsp;string&nbsp;EncryptByAES(string&nbsp;input,&nbsp;string&nbsp;key)<br />
{<br />
	if&nbsp;(string.IsNullOrWhiteSpace(input))<br />
	{<br />
		return&nbsp;input;<br />
	}<br />
	using&nbsp;(RijndaelManaged&nbsp;rijndaelManaged&nbsp;=&nbsp;new&nbsp;RijndaelManaged())<br />
	{<br />
		rijndaelManaged.Mode&nbsp;=&nbsp;CipherMode.ECB;<br />
		rijndaelManaged.Padding&nbsp;=&nbsp;PaddingMode.PKCS7;<br />
		rijndaelManaged.FeedbackSize&nbsp;=&nbsp;128;<br />
		byte[]&nbsp;data3&nbsp;=&nbsp;Enumerable.Range(0,&nbsp;key.Length&nbsp;/&nbsp;2).Select(x&nbsp;=&gt;&nbsp;Byte.Parse(key.Substring(x&nbsp;*&nbsp;2,&nbsp;2),&nbsp;NumberStyles.HexNumber)).ToArray();<br />
		rijndaelManaged.Key&nbsp;=&nbsp;data3;<br />
		ICryptoTransform&nbsp;encryptor&nbsp;=&nbsp;rijndaelManaged.CreateEncryptor(rijndaelManaged.Key,&nbsp;rijndaelManaged.IV);<br />
		using&nbsp;(MemoryStream&nbsp;msEncrypt&nbsp;=&nbsp;new&nbsp;MemoryStream())<br />
		{<br />
			using&nbsp;(CryptoStream&nbsp;csEncrypt&nbsp;=&nbsp;new&nbsp;CryptoStream(msEncrypt,&nbsp;encryptor,&nbsp;CryptoStreamMode.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;&nbsp;{<br />
				using&nbsp;(StreamWriter&nbsp;swEncrypt&nbsp;=&nbsp;new&nbsp;StreamWriter(csEncrypt))<br />
				{<br />
					swEncrypt.Write(input);<br />
				}<br />
				byte[]&nbsp;bytes&nbsp;=&nbsp;msEncrypt.ToArray();<br />
				//return&nbsp;Convert.ToBase64String(bytes);<br />
				return&nbsp;HexConvert.byteToHexStr(bytes);<br />
			}<br />
		}<br />
	}<br />
}<br />
</div><br />
<div class="txt_main">/// &lt;summary&gt;<br />
///&nbsp;返回解密后的字符串<br />
/// &lt;/summary&gt;<br />
/// &lt;param&nbsp;name="input"&gt;&lt;/param&gt;<br />
/// &lt;param&nbsp;name="key"&gt;秘钥&lt;/param&gt;<br />
/// &lt;returns&gt;&lt;/returns&gt;<br />
public&nbsp;static&nbsp;string&nbsp;DecryptByAES(string&nbsp;input,&nbsp;string&nbsp;key)<br />
{<br />
	if&nbsp;(string.IsNullOrWhiteSpace(input))<br />
	{<br />
		return&nbsp;input;<br />
	}<br />
	//var&nbsp;buffer&nbsp;=&nbsp;Convert.FromBase64String(input);<br />
	var&nbsp;buffer&nbsp;=&nbsp;HexConvert.strToToHexByte(input);<br />
	using&nbsp;(RijndaelManaged&nbsp;rijndaelManaged&nbsp;=&nbsp;new&nbsp;RijndaelManaged())<br />
	{<br />
		rijndaelManaged.Mode&nbsp;=&nbsp;CipherMode.ECB;<br />
		rijndaelManaged.Padding&nbsp;=&nbsp;PaddingMode.PKCS7;<br />
		rijndaelManaged.FeedbackSize&nbsp;=&nbsp;128;<br />
		byte[]&nbsp;data3&nbsp;=&nbsp;Enumerable.Range(0,&nbsp;key.Length&nbsp;/&nbsp;2).Select(x&nbsp;=&gt;&nbsp;Byte.Parse(key.Substring(x&nbsp;*&nbsp;2,&nbsp;2),&nbsp;NumberStyles.HexNumber)).ToArray();<br />
		rijndaelManaged.Key&nbsp;=&nbsp;data3;<br />
		ICryptoTransform&nbsp;decryptor&nbsp;=&nbsp;rijndaelManaged.CreateDecryptor(rijndaelManaged.Key,&nbsp;rijndaelManaged.IV);<br />
		using&nbsp;(MemoryStream&nbsp;msEncrypt&nbsp;=&nbsp;new&nbsp;MemoryStream(buffer))<br />
		{<br />
			using&nbsp;(CryptoStream&nbsp;csEncrypt&nbsp;=&nbsp;new&nbsp;CryptoStream(msEncrypt,&nbsp;decryptor,&nbsp;CryptoStreamMode.Read))<br />
			{<br />
				using&nbsp;(StreamReader&nbsp;srEncrypt&nbsp;=&nbsp;new&nbsp;StreamReader(csEncrypt))<br />
				{<br />
					return&nbsp;srEncrypt.ReadToEnd();<br />
				}<br />
			}<br />
		}<br />
	}<br />
}<br />
</div><br />
<br />
<h2>4、数据转换</h2><br />
<div class="txt_main">//字符串转换为字节数组<br />
byte[]&nbsp;originalBytes&nbsp;=&nbsp;System.Text.Encoding.UTF8.GetBytes(originalText);<br />
<br />
//&nbsp;进行Base64编码<br />
string&nbsp;base64Encoded&nbsp;=&nbsp;Convert.ToBase64String(originalBytes);<br />
<br />
//&nbsp;进行Base64解码<br />
byte[]&nbsp;base64DecodedBytes&nbsp;=&nbsp;Convert.FromBase64String(base64Encoded);<br />
<br />
//字节数组转字符串<br />
string&nbsp;base64DecodedText&nbsp;=&nbsp;System.Text.Encoding.UTF8.GetString(base64DecodedBytes);<br />
<br />
//16进制转base64字符串<br />
byte[]&nbsp;enterpriseCode_&nbsp;=&nbsp;HexConvert.strToToHexByte(data.enterpriseCode);<br />
string&nbsp;enterpriseCode&nbsp;=&nbsp;Convert.ToBase64String(enterpriseCode_);<br />
				<br />
/// &lt;summary&gt; <br />
///&nbsp;字节数组转16进制字符串 <br />
/// &lt;/summary&gt; <br />
/// &lt;param&nbsp;name="byteArray"&gt;&lt;/param&gt; <br />
/// &lt;returns&gt;&lt;/returns&gt; <br />
public&nbsp;static&nbsp;string&nbsp;byteToHexStr2(byte[]&nbsp;byteArray)<br />
{<br />
	string&nbsp;hexString&nbsp;=&nbsp;BitConverter.ToString(byteArray);<br />
	return&nbsp;hexString.Replace("-",&nbsp;"");<br />
}<br />
<br />
/// &lt;summary&gt; <br />
///&nbsp;字符串转16进制字节数组 <br />
/// &lt;/summary&gt; <br />
/// &lt;param&nbsp;name="hexString"&gt;&lt;/param&gt; <br />
/// &lt;returns&gt;&lt;/returns&gt; <br />
public&nbsp;static&nbsp;byte[]&nbsp;strToToHexByte(string&nbsp;hexString)<br />
{<br />
	hexString&nbsp;=&nbsp;hexString.Replace("&nbsp;",&nbsp;"");<br />
	if&nbsp;((hexString.Length&nbsp;%&nbsp;2)&nbsp;!=&nbsp;0)<br />
		hexString&nbsp;+=&nbsp;"&nbsp;";<br />
	byte[]&nbsp;returnBytes&nbsp;=&nbsp;new&nbsp;byte[hexString.Length&nbsp;/&nbsp;2];<br />
	for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;returnBytes.Length;&nbsp;i++)<br />
		returnBytes[i]&nbsp;=&nbsp;Convert.ToByte(hexString.Substring(i&nbsp;*&nbsp;2,&nbsp;2),&nbsp;16);<br />
	return&nbsp;returnBytes;<br />
}<br />
</div>]]></content:encoded>
<link>https://www.rickw.cn/blogview/339</link>
<dc:subject>C# .Net编程</dc:subject>
<dc:creator>rick</dc:creator>
<dc:date>2024-12-23 12:48:57</dc:date>
</item>
		
<item rdf:about="https://www.rickw.cn/blogview/332">
<title><![CDATA[C# 中实现几种幻灯片中的窗口特效]]></title>
	
<description><![CDATA[<ul><br />
<li>淡入淡出<br />
<li>变大变小<br />
<li>缓升缓降<br />
</ul></ol><br />]]></description>
<content:encoded><![CDATA[<ul><br />
<li>淡入淡出<br />
<li>变大变小<br />
<li>缓升缓降<br />
</ul></ol><br />
<br />
实现的代码片段参考如下：<br />
<br />
<strong>淡入淡出</strong><br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_wtbTuZPLSN54')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_wtbTuZPLSN54);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_wtbTuZPLSN54" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #007700">public&nbsp;</span><span style="color: #0000BB">Form1</span><span style="color: #007700">()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">InitializeComponent</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Opacity&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">timer1</span><span style="color: #007700">.</span><span style="color: #0000BB">Interval&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">10</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">timer1</span><span style="color: #007700">.</span><span style="color: #0000BB">Start</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;private&nbsp;</span><span style="color: #0000BB">void&nbsp;timer1_Tick</span><span style="color: #007700">(</span><span style="color: #0000BB">object&nbsp;sender</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">EventArgs&nbsp;e</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">isShow</span><span style="color: #007700">)<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;if&nbsp;(</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">&lt;&nbsp;</span><span style="color: #0000BB">height</span><span style="color: #007700">)<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;</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">+=&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">;<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;else<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;</span><span style="color: #0000BB">timer1</span><span style="color: #007700">.</span><span style="color: #0000BB">Stop</span><span style="color: #007700">();<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;&nbsp;&nbsp;&nbsp;&nbsp;else<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;if&nbsp;(</span><span style="color: #0000BB">ClientSize</span><span style="color: #007700">.</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">&gt;&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">)<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;</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">-=&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">;<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;else<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;</span><span style="color: #0000BB">timer1</span><span style="color: #007700">.</span><span style="color: #0000BB">Stop</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Close</span><span style="color: #007700">();<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;}&nbsp;</span><br />
</span><br />
</code></div><br />
<br />
<strong>变大变小</strong><br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_67dzzWofvCAF')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_67dzzWofvCAF);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_67dzzWofvCAF" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #007700">public&nbsp;</span><span style="color: #0000BB">Form2</span><span style="color: #007700">()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">InitializeComponent</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">height&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">Height</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Size&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Size</span><span style="color: #007700">(</span><span style="color: #0000BB">Width</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">timer1</span><span style="color: #007700">.</span><span style="color: #0000BB">Interval&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">10</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">timer1</span><span style="color: #007700">.</span><span style="color: #0000BB">Start</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;<br />&nbsp;private&nbsp;</span><span style="color: #0000BB">void&nbsp;timer1_Tick</span><span style="color: #007700">(</span><span style="color: #0000BB">object&nbsp;sender</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">EventArgs&nbsp;e</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">isShow</span><span style="color: #007700">)<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;if&nbsp;(</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">&lt;&nbsp;</span><span style="color: #0000BB">height</span><span style="color: #007700">)<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;</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">+=&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">;<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;else<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;</span><span style="color: #0000BB">timer1</span><span style="color: #007700">.</span><span style="color: #0000BB">Stop</span><span style="color: #007700">();<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;&nbsp;&nbsp;&nbsp;&nbsp;else<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;if&nbsp;(</span><span style="color: #0000BB">ClientSize</span><span style="color: #007700">.</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">&gt;&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">)<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;</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">-=&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">;<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;else<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;</span><span style="color: #0000BB">timer1</span><span style="color: #007700">.</span><span style="color: #0000BB">Stop</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Close</span><span style="color: #007700">();<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;}&nbsp;</span><br />
</span><br />
</code></div><br />
<br />
<strong>缓升缓降</strong><br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_vLypAa3OoSiY')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_vLypAa3OoSiY);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_vLypAa3OoSiY" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #007700">public&nbsp;</span><span style="color: #0000BB">Form3</span><span style="color: #007700">()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">InitializeComponent</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">timer1</span><span style="color: #007700">.</span><span style="color: #0000BB">Interval&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">10</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;</span><span style="color: #0000BB">void&nbsp;Form3_Load</span><span style="color: #007700">(</span><span style="color: #0000BB">object&nbsp;sender</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">EventArgs&nbsp;e</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Location&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Point</span><span style="color: #007700">(</span><span style="color: #0000BB">screenRect</span><span style="color: #007700">.</span><span style="color: #0000BB">Width&nbsp;</span><span style="color: #007700">-&nbsp;</span><span style="color: #0000BB">Width</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">screenRect</span><span style="color: #007700">.</span><span style="color: #0000BB">Height</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">timer1</span><span style="color: #007700">.</span><span style="color: #0000BB">Start</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;private&nbsp;</span><span style="color: #0000BB">void&nbsp;timer1_Tick</span><span style="color: #007700">(</span><span style="color: #0000BB">object&nbsp;sender</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">EventArgs&nbsp;e</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">isShow</span><span style="color: #007700">)<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;if&nbsp;(</span><span style="color: #0000BB">Location</span><span style="color: #007700">.</span><span style="color: #0000BB">Y&nbsp;</span><span style="color: #007700">&gt;&nbsp;</span><span style="color: #0000BB">screenRect</span><span style="color: #007700">.</span><span style="color: #0000BB">Height</span><span style="color: #007700">-</span><span style="color: #0000BB">Height</span><span style="color: #007700">)<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;</span><span style="color: #0000BB">Location&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Point</span><span style="color: #007700">(</span><span style="color: #0000BB">Location</span><span style="color: #007700">.</span><span style="color: #0000BB">X</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Location</span><span style="color: #007700">.</span><span style="color: #0000BB">Y&nbsp;</span><span style="color: #007700">-&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">);<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;else<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;</span><span style="color: #0000BB">timer1</span><span style="color: #007700">.</span><span style="color: #0000BB">Stop</span><span style="color: #007700">();<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;&nbsp;&nbsp;&nbsp;&nbsp;else<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;if&nbsp;(</span><span style="color: #0000BB">Location</span><span style="color: #007700">.</span><span style="color: #0000BB">Y&nbsp;</span><span style="color: #007700">&lt;&nbsp;</span><span style="color: #0000BB">screenRect</span><span style="color: #007700">.</span><span style="color: #0000BB">Height&nbsp;</span><span style="color: #007700">)<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;</span><span style="color: #0000BB">Location&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Point</span><span style="color: #007700">(</span><span style="color: #0000BB">Location</span><span style="color: #007700">.</span><span style="color: #0000BB">X</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">Location</span><span style="color: #007700">.</span><span style="color: #0000BB">Y&nbsp;</span><span style="color: #007700">+&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">);<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;else<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;</span><span style="color: #0000BB">timer1</span><span style="color: #007700">.</span><span style="color: #0000BB">Stop</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Close</span><span style="color: #007700">();<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 /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><br />
</span><br />
</code></div>]]></content:encoded>
<link>https://www.rickw.cn/blogview/332</link>
<dc:subject>C# .Net编程</dc:subject>
<dc:creator>rick</dc:creator>
<dc:date>2024-01-05 21:33:35</dc:date>
</item>
		
<item rdf:about="https://www.rickw.cn/blogview/324">
<title><![CDATA[C#中byte[]字节数组复制的5种常用方法]]></title>
	
<description><![CDATA[简单总结了5种字节数组的复制方法<br />
<br />
1、for循环实现复制<br />
较为原始的遍历写法，不太推荐<br />
<br />]]></description>
<content:encoded><![CDATA[简单总结了5种字节数组的复制方法<br />
<br />
1、for循环实现复制<br />
较为原始的遍历写法，不太推荐<br />
<br />
byte[]&nbsp;data&nbsp;=&nbsp;new&nbsp;byte[]{0,1,2,3,4,5,6,7,8,9};<br />
<br />
byte[]&nbsp;data1&nbsp;=&nbsp;new&nbsp;byte[data.length];<br />
<br />
for(int&nbsp;i=0;i&lt;data1.length;i++)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data1[i]&nbsp;=&nbsp;data[i];<br />
}<br />
2、Arrary.Copy实现复制<br />
在CLR处理机制中最灵活，最强大,可装箱，拆箱复制，可加宽CLR基元类型，可内部判断实现了IFarmattable接口的兼容转换，当然这种强大方式必然会带来一定的性能损失。还有个CopyTo也是一样的。<br />
<br />
byte[]&nbsp;data&nbsp;=&nbsp;new&nbsp;byte[]{0,1,2,3,4,5,6,7,8,9};<br />
byte[]&nbsp;data1&nbsp;=&nbsp;new&nbsp;byte[data.length];<br />
Array.Copy(data,data1,data.length);//源数据data，目标数据data1，复制长度data.length<br />
3、Clone实现复制<br />
Clone会创建新数组，分配内存，不宜用在需要保持高刷新率下的场景<br />
<br />
&nbsp;byte[]&nbsp;data&nbsp;=&nbsp;new&nbsp;byte[]{0,1,2,3,4,5,6,7,8,9};<br />
&nbsp;byte[]&nbsp;data1;<br />
&nbsp;data1&nbsp;=&nbsp;(byte[])data&nbsp;.Clone()<br />
4、Buffer.BlockCopy实现复制<br />
则从本质上以字节为复制单位，这在底层语言C，C++的处理优势上，同理，效率之高可以理解。当然如果对性能要求不高，Copy足矣，毕竟在上千次复制下，三者基本没消耗多少时间。使用时可根据项目需求斟酌选择！<br />
<br />
&nbsp;byte[]&nbsp;srcArray&nbsp;=&nbsp;new&nbsp;byte[]&nbsp;{&nbsp;0x01,&nbsp;0x02,&nbsp;0x03,&nbsp;0x04&nbsp;};<br />
&nbsp;byte[]&nbsp;dstArray&nbsp;=&nbsp;new&nbsp;byte[srcArray.Length];<br />
&nbsp;Buffer.BlockCopy(srcArray,&nbsp;0,&nbsp;dstArray,&nbsp;0,&nbsp;srcArray.Length);<br />
&nbsp;//源数据srcArray&nbsp;，&nbsp;起始位置0，目标数组dstArray&nbsp;，开始位置0，多少长度&nbsp;srcArray.Length<br />
5、Array.ConstrainedCopy&nbsp;实现复制<br />
对复制要求严格，只能是同类型或者源数组类型是目标类型的派生元素类型，不执行装箱，拆箱，向下转换。<br />
<br />
&nbsp;byte[]&nbsp;srcArray&nbsp;=&nbsp;new&nbsp;byte[]&nbsp;{&nbsp;0x01,&nbsp;0x02,&nbsp;0x03,&nbsp;0x04&nbsp;};<br />
&nbsp;byte[]&nbsp;dstArray&nbsp;=&nbsp;new&nbsp;byte[srcArray.Length];<br />
&nbsp;Array.ConstrainedCopy(srcArray,&nbsp;0,&nbsp;dstArray,&nbsp;0,&nbsp;srcArray.Length);<br />
&nbsp;//源数据srcArray&nbsp;，&nbsp;起始位置0，目标数组dstArray&nbsp;，开始位置0，多少长度&nbsp;srcArray.Length]]></content:encoded>
<link>https://www.rickw.cn/blogview/324</link>
<dc:subject>C# .Net编程</dc:subject>
<dc:creator>rick</dc:creator>
<dc:date>2023-12-27 11:17:44</dc:date>
</item>
		
<item rdf:about="https://www.rickw.cn/blogview/317">
<title><![CDATA[C# 使用 HttpClient错误？SocketException：现有连接被远程主机强行关闭]]></title>
	
<description><![CDATA[C#中使用&nbsp;HttpClient&nbsp;访问https站点，出现以下错误。<br />
<br />
System.AggregateException<br />
&nbsp;&nbsp;HResult&nbsp;=&nbsp;0x80131500<br />
&nbsp;&nbsp;Message&nbsp;=发生一个或多个错误。<br />]]></description>
<content:encoded><![CDATA[C#中使用&nbsp;HttpClient&nbsp;访问https站点，出现以下错误。<br />
<br />
System.AggregateException<br />
&nbsp;&nbsp;HResult&nbsp;=&nbsp;0x80131500<br />
&nbsp;&nbsp;Message&nbsp;=发生一个或多个错误。<br />
&nbsp;&nbsp;来源=&nbsp;System.Private.CoreLib<br />
&nbsp;&nbsp;堆栈跟踪：<br />
&nbsp;&nbsp;&nbsp;在System.Threading.Tasks.Task`1.GetResultCore（Boolean&nbsp;waitCompletionNotification）<br />
&nbsp;&nbsp;<br />
内部例外1：<br />
HttpRequestException：无法建立SSL连接，请参阅内部异常。<br />
<br />
内部例外2：<br />
IOException：无法从传输连接中读取数据：现有连接被远程主机强行关闭。<br />
<br />
内部例外3：<br />
SocketException：现有连接被远程主机强行关闭<br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_3xrsAHrcCs8f')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_3xrsAHrcCs8f);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_3xrsAHrcCs8f" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #0000BB"><br /></span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">Program<br /></span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;</span><span style="color: #0000BB">void&nbsp;Main</span><span style="color: #007700">(</span><span style="color: #0000BB">string</span><span style="color: #007700">[]&nbsp;</span><span style="color: #0000BB">args</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;</span><span style="color: #0000BB">url&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"https://google.com"</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;(</span><span style="color: #0000BB">statusCode</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">html</span><span style="color: #007700">)&nbsp;=&nbsp;</span><span style="color: #0000BB">requestString</span><span style="color: #007700">(</span><span style="color: #0000BB">url</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Console</span><span style="color: #007700">.</span><span style="color: #0000BB">WriteLine</span><span style="color: #007700">(</span><span style="color: #DD0000">"%d&nbsp;%s"</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">statusCode</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">html</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;</span><span style="color: #0000BB">CookieContainer&nbsp;cc&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">CookieContainer</span><span style="color: #007700">();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;</span><span style="color: #0000BB">HttpClientHandler&nbsp;handler&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">HttpClientHandler&nbsp;</span><span style="color: #007700">{&nbsp;</span><span style="color: #0000BB">AllowAutoRedirect&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">false</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">CookieContainer&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">cc&nbsp;</span><span style="color: #007700">};<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;</span><span style="color: #0000BB">async&nbsp;Task</span><span style="color: #007700">&lt;(</span><span style="color: #0000BB">int&nbsp;statusCode</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">string&nbsp;content</span><span style="color: #007700">)&gt;&nbsp;</span><span style="color: #0000BB">requestStringAsync</span><span style="color: #007700">(</span><span style="color: #0000BB">string&nbsp;url</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">ServicePointManager</span><span style="color: #007700">.</span><span style="color: #0000BB">ServerCertificateValidationCallback&nbsp;</span><span style="color: #007700">+=&nbsp;(</span><span style="color: #0000BB">sender</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">cert</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">chain</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">sslPolicyErrors</span><span style="color: #007700">)&nbsp;=&gt;&nbsp;</span><span style="color: #0000BB">true</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">ServicePointManager</span><span style="color: #007700">.</span><span style="color: #0000BB">SecurityProtocol&nbsp;</span><span style="color: #007700">|=&nbsp;</span><span style="color: #0000BB">SecurityProtocolType</span><span style="color: #007700">.</span><span style="color: #0000BB">Tls&nbsp;</span><span style="color: #007700">|&nbsp;</span><span style="color: #0000BB">SecurityProtocolType</span><span style="color: #007700">.</span><span style="color: #0000BB">Tls11&nbsp;</span><span style="color: #007700">|&nbsp;</span><span style="color: #0000BB">SecurityProtocolType</span><span style="color: #007700">.</span><span style="color: #0000BB">Tls12</span><span style="color: #007700">;<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;&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;</span><span style="color: #FF8000">//&nbsp;|&nbsp;SecurityProtocolType.Ssl3;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">using&nbsp;</span><span style="color: #007700">(var&nbsp;</span><span style="color: #0000BB">request&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">HttpRequestMessage&nbsp;</span><span style="color: #007700">{&nbsp;</span><span style="color: #0000BB">RequestUri&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Uri</span><span style="color: #007700">(</span><span style="color: #0000BB">url</span><span style="color: #007700">),&nbsp;</span><span style="color: #0000BB">Method&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">HttpMethod</span><span style="color: #007700">.</span><span style="color: #0000BB">Get&nbsp;</span><span style="color: #007700">})<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">using&nbsp;</span><span style="color: #007700">(var&nbsp;</span><span style="color: #0000BB">client&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">HttpClient</span><span style="color: #007700">(</span><span style="color: #0000BB">handler</span><span style="color: #007700">))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;</span><span style="color: #0000BB">response&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">await&nbsp;client</span><span style="color: #007700">.</span><span style="color: #0000BB">SendAsync</span><span style="color: #007700">(</span><span style="color: #0000BB">request</span><span style="color: #007700">);&nbsp;</span><span style="color: #FF8000">//&nbsp;Error&nbsp;(actual&nbsp;line)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">var&nbsp;</span><span style="color: #0000BB">statusCode&nbsp;</span><span style="color: #007700">=&nbsp;(int)</span><span style="color: #0000BB">response</span><span style="color: #007700">.</span><span style="color: #0000BB">StatusCode</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;</span><span style="color: #0000BB">content&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">await&nbsp;response</span><span style="color: #007700">.</span><span style="color: #0000BB">Content</span><span style="color: #007700">.</span><span style="color: #0000BB">ReadAsStringAsync</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(</span><span style="color: #0000BB">statusCode</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">content</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;(</span><span style="color: #0000BB">int&nbsp;statusCode</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">string&nbsp;content</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">requestString</span><span style="color: #007700">(</span><span style="color: #0000BB">string&nbsp;url</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span style="color: #0000BB">requestStringAsync</span><span style="color: #007700">(</span><span style="color: #0000BB">url</span><span style="color: #007700">).</span><span style="color: #0000BB">Result</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}&nbsp;</span><br />
</span><br />
</code></div><br />
<br />
按上面调整&nbsp;ServicePointManager&nbsp;后在&nbsp;.net&nbsp;framework环境中就可以正常运行了。<br />
<br />
在.Net&nbsp;Core的环境中还可能发生问题。<br />
<br />
.Net&nbsp;Core中可以使用以下机制之一来配置进程以使用较旧的HttpClientHandler：<br />
<br />
从代码中，使用AppContext类：<br />
<br />
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler",&nbsp;false);<br />
<br />
也可以通过配置文件来设置AppContext开关。<br />
<br />
可以通过环境变量DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER实现相同的目的。<br />
要选择退出，请将值设置为false或0。]]></content:encoded>
<link>https://www.rickw.cn/blogview/317</link>
<dc:subject>C# .Net编程</dc:subject>
<dc:creator>rick</dc:creator>
<dc:date>2023-12-22 00:17:40</dc:date>
</item>
		
<item rdf:about="https://www.rickw.cn/blogview/316">
<title><![CDATA[C#屏幕截图，指定区域截图，窗口截图的实现]]></title>
	
<description><![CDATA[核心方法是使用Graphics类的CopyFromScreen方法将窗口的内容复制到位图中。<br />
指定区域截图，只需要将屏幕图片按区域裁剪即可。<br />
指定窗口截图，先获取窗口的位置和大小，然后转化为指定区域截图了。<br />
如果是制作指定窗口的录屏程序时，需要注意实时跟踪窗口的位置和大小（窗口位置和大小可能会调整变化）。<br />
其它的就没有特别的了。<br />]]></description>
<content:encoded><![CDATA[核心方法是使用Graphics类的CopyFromScreen方法将窗口的内容复制到位图中。<br />
指定区域截图，只需要将屏幕图片按区域裁剪即可。<br />
指定窗口截图，先获取窗口的位置和大小，然后转化为指定区域截图了。<br />
如果是制作指定窗口的录屏程序时，需要注意实时跟踪窗口的位置和大小（窗口位置和大小可能会调整变化）。<br />
其它的就没有特别的了。<br />
<br />
例子代码：<br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_22CT6eeC312v')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_22CT6eeC312v);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_22CT6eeC312v" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #0000BB">using&nbsp;System</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">using&nbsp;System</span><span style="color: #007700">.</span><span style="color: #0000BB">Drawing</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">using&nbsp;System</span><span style="color: #007700">.</span><span style="color: #0000BB">Runtime</span><span style="color: #007700">.</span><span style="color: #0000BB">InteropServices</span><span style="color: #007700">;<br /><br />class&nbsp;</span><span style="color: #0000BB">Program<br /></span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style="color: #0000BB">DllImport</span><span style="color: #007700">(</span><span style="color: #DD0000">"user32.dll"</span><span style="color: #007700">)]<br />&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;</span><span style="color: #0000BB">extern&nbsp;IntPtr&nbsp;GetForegroundWindow</span><span style="color: #007700">();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style="color: #0000BB">DllImport</span><span style="color: #007700">(</span><span style="color: #DD0000">"user32.dll"</span><span style="color: #007700">)]<br />&nbsp;&nbsp;&nbsp;&nbsp;[return:&nbsp;</span><span style="color: #0000BB">MarshalAs</span><span style="color: #007700">(</span><span style="color: #0000BB">UnmanagedType</span><span style="color: #007700">.</span><span style="color: #0000BB">Bool</span><span style="color: #007700">)]<br />&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;</span><span style="color: #0000BB">extern&nbsp;bool&nbsp;GetWindowRect</span><span style="color: #007700">(</span><span style="color: #0000BB">IntPtr&nbsp;hWnd</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">out&nbsp;RECT&nbsp;lpRect</span><span style="color: #007700">);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style="color: #0000BB">StructLayout</span><span style="color: #007700">(</span><span style="color: #0000BB">LayoutKind</span><span style="color: #007700">.</span><span style="color: #0000BB">Sequential</span><span style="color: #007700">)]<br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">struct&nbsp;RECT<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">int&nbsp;Left</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">int&nbsp;Top</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">int&nbsp;Right</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">int&nbsp;Bottom</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;</span><span style="color: #0000BB">void&nbsp;Main</span><span style="color: #007700">()<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;获取活动窗口句柄<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">IntPtr&nbsp;hWnd&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">GetForegroundWindow</span><span style="color: #007700">();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;获取窗口位置和大小<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">RECT&nbsp;windowRect</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">GetWindowRect</span><span style="color: #007700">(</span><span style="color: #0000BB">hWnd</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">out&nbsp;windowRect</span><span style="color: #007700">);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;创建Bitmap对象<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">using&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">Bitmap&nbsp;bmp&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Bitmap</span><span style="color: #007700">(</span><span style="color: #0000BB">windowRect</span><span style="color: #007700">.</span><span style="color: #0000BB">Right&nbsp;</span><span style="color: #007700">-&nbsp;</span><span style="color: #0000BB">windowRect</span><span style="color: #007700">.</span><span style="color: #0000BB">Left</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">windowRect</span><span style="color: #007700">.</span><span style="color: #0000BB">Bottom&nbsp;</span><span style="color: #007700">-&nbsp;</span><span style="color: #0000BB">windowRect</span><span style="color: #007700">.</span><span style="color: #0000BB">Top</span><span style="color: #007700">))<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;</span><span style="color: #FF8000">//&nbsp;创建Graphics对象<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">using&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">Graphics&nbsp;g&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">Graphics</span><span style="color: #007700">.</span><span style="color: #0000BB">FromImage</span><span style="color: #007700">(</span><span style="color: #0000BB">bmp</span><span style="color: #007700">))<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;</span><span style="color: #FF8000">//&nbsp;将窗口内容绘制到Bitmap中<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;</span><span style="color: #0000BB">g</span><span style="color: #007700">.</span><span style="color: #0000BB">CopyFromScreen</span><span style="color: #007700">(new&nbsp;</span><span style="color: #0000BB">Point</span><span style="color: #007700">(</span><span style="color: #0000BB">windowRect</span><span style="color: #007700">.</span><span style="color: #0000BB">Left</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">windowRect</span><span style="color: #007700">.</span><span style="color: #0000BB">Top</span><span style="color: #007700">),&nbsp;</span><span style="color: #0000BB">Point</span><span style="color: #007700">.Empty,&nbsp;</span><span style="color: #0000BB">bmp</span><span style="color: #007700">.</span><span style="color: #0000BB">Size</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;保存屏幕截图（可根据需要进行保存）<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">bmp</span><span style="color: #007700">.</span><span style="color: #0000BB">Save</span><span style="color: #007700">(</span><span style="color: #DD0000">"screenshot.png"</span><span style="color: #007700">);<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;</span><span style="color: #0000BB">Console</span><span style="color: #007700">.</span><span style="color: #0000BB">WriteLine</span><span style="color: #007700">(</span><span style="color: #DD0000">"屏幕截图已保存成功。"</span><span style="color: #007700">);<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;&nbsp;&nbsp;&nbsp;&nbsp;catch&nbsp;(</span><span style="color: #0000BB">Exception&nbsp;ex</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Console</span><span style="color: #007700">.</span><span style="color: #0000BB">WriteLine</span><span style="color: #007700">(</span><span style="color: #DD0000">"发生异常："&nbsp;</span><span style="color: #007700">+&nbsp;</span><span style="color: #0000BB">ex</span><span style="color: #007700">.</span><span style="color: #0000BB">Message</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}&nbsp;</span><br />
</span><br />
</code></div>]]></content:encoded>
<link>https://www.rickw.cn/blogview/316</link>
<dc:subject>C# .Net编程</dc:subject>
<dc:creator>rick</dc:creator>
<dc:date>2023-12-21 12:11:46</dc:date>
</item>
		
<item rdf:about="https://www.rickw.cn/blogview/310">
<title><![CDATA[C#同步代码中调用async异步方法.Result等待导致阻塞死锁deadlock的问题]]></title>
	
<description><![CDATA[在&nbsp;UI界面或者ASP.NET的同步代码中调用async的异步代码时如果async和task.Result混用会出现线程被阻塞锁死deadlock的情况。<br />
<strong>导致死锁的例子代码：</strong><br />
<div class="txt_main">public&nbsp;static&nbsp;async&nbsp;Task&lt;string&gt;&nbsp;GetWebPageAsync(string&nbsp;uri)<br />
{<br />
&nbsp;&nbsp;//这里的&nbsp;client&nbsp;是全局初始化的&nbsp;HttpClient&nbsp;对象<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;=&nbsp;await&nbsp;client.GetStringAsync(uri);<br />
}<br />
<br />
public&nbsp;void&nbsp;Button1_Click(object&nbsp;sender,&nbsp;EventArg&nbsp;e)<br />
{<br />
&nbsp;&nbsp;var&nbsp;webTask&nbsp;=&nbsp;GetWebPageAsync("_get_url_");<br />
&nbsp;&nbsp;textBox1.Text&nbsp;=&nbsp;webTask.Result;<br />
}</div><br />
]]></description>
<content:encoded><![CDATA[在&nbsp;UI界面或者ASP.NET的同步代码中调用async的异步代码时如果async和task.Result混用会出现线程被阻塞锁死deadlock的情况。<br />
<strong>导致死锁的例子代码：</strong><br />
<div class="txt_main">public&nbsp;static&nbsp;async&nbsp;Task&lt;string&gt;&nbsp;GetWebPageAsync(string&nbsp;uri)<br />
{<br />
&nbsp;&nbsp;//这里的&nbsp;client&nbsp;是全局初始化的&nbsp;HttpClient&nbsp;对象<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;=&nbsp;await&nbsp;client.GetStringAsync(uri);<br />
}<br />
<br />
public&nbsp;void&nbsp;Button1_Click(object&nbsp;sender,&nbsp;EventArg&nbsp;e)<br />
{<br />
&nbsp;&nbsp;var&nbsp;webTask&nbsp;=&nbsp;GetWebPageAsync("_get_url_");<br />
&nbsp;&nbsp;textBox1.Text&nbsp;=&nbsp;webTask.Result;<br />
}</div><br />
<br />
<br />
<h2>阻止死锁的两种办法：</h2><br />
<div class="txt_main"><strong>一、使用&nbsp;ConfigureAwait(false)</strong><br />
<div class="txt_main">public&nbsp;static&nbsp;async&nbsp;Task&lt;string&gt;&nbsp;GetWebPageAsync(string&nbsp;uri)<br />
{<br />
&nbsp;&nbsp;//这里的&nbsp;client&nbsp;是全局初始化的&nbsp;HttpClient&nbsp;对象<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;=&nbsp;await&nbsp;client.GetStringAsync(uri)<font color="red">.ConfigureAwait(false)</font>;<br />
}</div><br />
<br />
<div class="code_head"></div><div class="code_main quote"><blockquote>默认情况下，当您使用async/await时，它将在开始请求的原始线程上继续运行(状态机)。但是，如果当前另一个长时间运行的进程已经接管了该线程，那么你就不得不等待它完成。要避免这个问题，可以使用ConfigureAwait的方法和false参数。当你用这个方法的时候，这将告诉Task它可以在任何可用的线程上恢复自己继续运行，而不是等待最初创建它的线程。这将加快响应速度并避免许多死锁。<br />
<br />
但是，当使用此方法后，线程同步上下文将丢失，从而转变成异步操作，如果在之后继续操作界面元素等，会提示线程不安全。</blockquote></div><br />
<br />
<strong>二、使用&nbsp;异步Async&nbsp;方法进行调用：</strong><br />
<div class="txt_main">public&nbsp;<font color="red">async</font>&nbsp;void&nbsp;Button1_Click(object&nbsp;sender,&nbsp;EventArg&nbsp;e)<br />
{<br />
&nbsp;&nbsp;var&nbsp;webTask&nbsp;=&nbsp;GetWebPageAsync("_get_url_");<br />
&nbsp;&nbsp;textBox1.Text&nbsp;=&nbsp;webTask.Result;<br />
}</div><br />
</div>]]></content:encoded>
<link>https://www.rickw.cn/blogview/310</link>
<dc:subject>C# .Net编程</dc:subject>
<dc:creator>rick</dc:creator>
<dc:date>2023-12-17 11:34:09</dc:date>
</item>
		
<item rdf:about="https://www.rickw.cn/blogview/300">
<title><![CDATA[解决C#编译问题 CS 1617：/langversion的选项“10”无效]]></title>
	
<description><![CDATA[这个选项是开启C#10的语言特性支持。<br />
和VS版本有关，如果你使用的是VS2019，那么关闭项目，用文本打开csproj文件，将&lt;LangVersion&gt;10.0&lt;/LangVersion&gt;改为&lt;LangVersion&gt;9.0&lt;/LangVersion&gt;<br />
<br />
或者升级使用VS&nbsp;2022打开项目进行编译。<br />
]]></description>
<content:encoded><![CDATA[在&nbsp;UI界面或者ASP.NET的同步代码中调用async的异步代码时如果async和task.Result混用会出现线程被阻塞锁死deadlock的情况。<br />
<strong>导致死锁的例子代码：</strong><br />
<div class="txt_main">public&nbsp;static&nbsp;async&nbsp;Task&lt;string&gt;&nbsp;GetWebPageAsync(string&nbsp;uri)<br />
{<br />
&nbsp;&nbsp;//这里的&nbsp;client&nbsp;是全局初始化的&nbsp;HttpClient&nbsp;对象<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;=&nbsp;await&nbsp;client.GetStringAsync(uri);<br />
}<br />
<br />
public&nbsp;void&nbsp;Button1_Click(object&nbsp;sender,&nbsp;EventArg&nbsp;e)<br />
{<br />
&nbsp;&nbsp;var&nbsp;webTask&nbsp;=&nbsp;GetWebPageAsync("_get_url_");<br />
&nbsp;&nbsp;textBox1.Text&nbsp;=&nbsp;webTask.Result;<br />
}</div><br />
<br />
<br />
<h2>阻止死锁的两种办法：</h2><br />
<div class="txt_main"><strong>一、使用&nbsp;ConfigureAwait(false)</strong><br />
<div class="txt_main">public&nbsp;static&nbsp;async&nbsp;Task&lt;string&gt;&nbsp;GetWebPageAsync(string&nbsp;uri)<br />
{<br />
&nbsp;&nbsp;//这里的&nbsp;client&nbsp;是全局初始化的&nbsp;HttpClient&nbsp;对象<br />
&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;=&nbsp;await&nbsp;client.GetStringAsync(uri)<font color="red">.ConfigureAwait(false)</font>;<br />
}</div><br />
<br />
<div class="code_head"></div><div class="code_main quote"><blockquote>默认情况下，当您使用async/await时，它将在开始请求的原始线程上继续运行(状态机)。但是，如果当前另一个长时间运行的进程已经接管了该线程，那么你就不得不等待它完成。要避免这个问题，可以使用ConfigureAwait的方法和false参数。当你用这个方法的时候，这将告诉Task它可以在任何可用的线程上恢复自己继续运行，而不是等待最初创建它的线程。这将加快响应速度并避免许多死锁。<br />
<br />
但是，当使用此方法后，线程同步上下文将丢失，从而转变成异步操作，如果在之后继续操作界面元素等，会提示线程不安全。</blockquote></div><br />
<br />
<strong>二、使用&nbsp;异步Async&nbsp;方法进行调用：</strong><br />
<div class="txt_main">public&nbsp;<font color="red">async</font>&nbsp;void&nbsp;Button1_Click(object&nbsp;sender,&nbsp;EventArg&nbsp;e)<br />
{<br />
&nbsp;&nbsp;var&nbsp;webTask&nbsp;=&nbsp;GetWebPageAsync("_get_url_");<br />
&nbsp;&nbsp;textBox1.Text&nbsp;=&nbsp;webTask.Result;<br />
}</div><br />
</div>]]></content:encoded>
<link>https://www.rickw.cn/blogview/300</link>
<dc:subject>C# .Net编程</dc:subject>
<dc:creator>rick</dc:creator>
<dc:date>2023-12-10 11:58:25</dc:date>
</item>
		
<item rdf:about="https://www.rickw.cn/blogview/283">
<title><![CDATA[Jurassic [C# .Net JavaScript引擎]限制脚本执行时间，防止死循环]]></title>
	
<description><![CDATA[想象一下在js引擎中执行如下代码：<br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_PkpmemSZp272')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_PkpmemSZp272);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_PkpmemSZp272" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #007700">try&nbsp;{}<br />finally&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(</span><span style="color: #0000BB">true</span><span style="color: #007700">);}&nbsp;</span><br />
</span><br />
</code></div><br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_oZRqt72fpFkC')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_oZRqt72fpFkC);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_oZRqt72fpFkC" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #0000BB">&nbsp;</span><span style="color: #007700">while&nbsp;(</span><span style="color: #0000BB">true</span><span style="color: #007700">);&nbsp;&nbsp;</span><br />
</span><br />
</code></div><br />
这样一个无限循环的js代码在&nbsp;ScriptEngine.Execute(String&nbsp;code)的调用中将永远不会返回。<br />
]]></description>
<content:encoded><![CDATA[想象一下在js引擎中执行如下代码：<br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_NE7fLkU5fadR')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_NE7fLkU5fadR);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_NE7fLkU5fadR" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #007700">try&nbsp;{}<br />finally&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(</span><span style="color: #0000BB">true</span><span style="color: #007700">);}&nbsp;</span><br />
</span><br />
</code></div><br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_YgX051aEN1nI')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_YgX051aEN1nI);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_YgX051aEN1nI" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #0000BB">&nbsp;</span><span style="color: #007700">while&nbsp;(</span><span style="color: #0000BB">true</span><span style="color: #007700">);&nbsp;&nbsp;</span><br />
</span><br />
</code></div><br />
这样一个无限循环的js代码在&nbsp;ScriptEngine.Execute(String&nbsp;code)的调用中将永远不会返回。<br />
<br />
Jurassic没有本身没有实现限制脚本执行时间的功能。由于Jurassic将JavaScript方法编译为IL代码，没有简单的方式来实现超时功能而不影响性能。但是，我们可以在执行脚本的线程中调用Thread.Abort()引发ThreadAbortException来终止脚本的执行。<br />
<h2>一种实现方式：</h2><br />
<div class="txt_main">在新线程中执行&nbsp;ScriptEngine.Execute()，在当前线程中进行等待并计时。当新线程在规定的时间内未完成，则在当前线程中调用<br />
thread.Abort()来终止新线程，并抛出一个超时的异常(TimeOutException)。<br />
</div><br />
<br />
<h2>用于限制脚本执行时间的Helper类（ScriptTimeoutHelper）</h2><br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_RHmG5B94Ovde')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_RHmG5B94Ovde);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_RHmG5B94Ovde" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #0000BB">using&nbsp;System</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">using&nbsp;System</span><span style="color: #007700">.</span><span style="color: #0000BB">Runtime</span><span style="color: #007700">.</span><span style="color: #0000BB">ExceptionServices</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">using&nbsp;System</span><span style="color: #007700">.</span><span style="color: #0000BB">Threading</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">using&nbsp;System</span><span style="color: #007700">.</span><span style="color: #0000BB">Threading</span><span style="color: #007700">.</span><span style="color: #0000BB">Tasks</span><span style="color: #007700">;<br /><br />namespace&nbsp;</span><span style="color: #0000BB">JurassicTimeoutHelper<br /></span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">///&nbsp;&lt;summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Allows&nbsp;to&nbsp;limit&nbsp;execution&nbsp;time&nbsp;of&nbsp;a&nbsp;Jurassic&nbsp;Script&nbsp;by&nbsp;internally&nbsp;using&nbsp;the<br />&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;technique&nbsp;of&nbsp;aborting&nbsp;a&nbsp;thread.<br />&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;class&nbsp;</span><span style="color: #0000BB">ScriptTimeoutHelper<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;</span><span style="color: #0000BB">HandlerState&nbsp;currentState</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">ScriptTimeoutHelper</span><span style="color: #007700">()<br />&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;</span><span style="color: #FF8000">///&nbsp;&lt;summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Runs&nbsp;the&nbsp;specified&nbsp;&lt;see&nbsp;cref="Action"/&gt;&nbsp;in&nbsp;the&nbsp;current&nbsp;thread,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;applying&nbsp;the&nbsp;given&nbsp;timeout.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;When&nbsp;the&nbsp;handler&nbsp;times&nbsp;out,&nbsp;a&nbsp;&lt;see&nbsp;cref="ThreadAbortException"/&gt;&nbsp;is<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;raised&nbsp;in&nbsp;the&nbsp;current&nbsp;thread&nbsp;to&nbsp;break.&nbsp;However,&nbsp;this&nbsp;is&nbsp;managed<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;internally&nbsp;so&nbsp;it&nbsp;does&nbsp;not&nbsp;affect&nbsp;the&nbsp;caller&nbsp;of&nbsp;this&nbsp;method&nbsp;(i.e.&nbsp;it&nbsp;is<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;ensured&nbsp;that&nbsp;a&nbsp;&lt;see&nbsp;cref="ThreadAbortException"/&gt;&nbsp;does&nbsp;not&nbsp;flow&nbsp;through<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;this&nbsp;method&nbsp;or&nbsp;raised&nbsp;after&nbsp;this&nbsp;method&nbsp;returns).<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;exception&nbsp;cref="TimeoutException"&gt;Thrown&nbsp;when&nbsp;the&nbsp;handler&nbsp;times&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;out.&lt;/exception&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;param&nbsp;name="handler"&gt;&lt;/param&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;param&nbsp;name="timeout"&gt;&lt;/param&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;</span><span style="color: #0000BB">void&nbsp;RunWithTimeout</span><span style="color: #007700">(</span><span style="color: #0000BB">Action&nbsp;handler</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">int&nbsp;timeout</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">currentState&nbsp;</span><span style="color: #007700">!=&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;</span><span style="color: #0000BB">InvalidOperationException</span><span style="color: #007700">(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$</span><span style="color: #DD0000">"Cannot&nbsp;recursively&nbsp;call&nbsp;{nameof(RunWithTimeout)}."</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">handler&nbsp;</span><span style="color: #007700">==&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;</span><span style="color: #0000BB">ArgumentException</span><span style="color: #007700">(</span><span style="color: #0000BB">nameof</span><span style="color: #007700">(</span><span style="color: #0000BB">handler</span><span style="color: #007700">));<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Throw&nbsp;the&nbsp;TimeoutException&nbsp;immediately&nbsp;when&nbsp;the&nbsp;timeout&nbsp;is&nbsp;0.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;(</span><span style="color: #0000BB">timeout&nbsp;</span><span style="color: #007700">==&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;</span><span style="color: #0000BB">TimeoutException</span><span style="color: #007700">();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">ExceptionDispatchInfo&nbsp;caughtException&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">using&nbsp;</span><span style="color: #007700">(var&nbsp;</span><span style="color: #0000BB">state&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">currentState&nbsp;</span><span style="color: #007700">=<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;</span><span style="color: #0000BB">HandlerState</span><span style="color: #007700">(</span><span style="color: #0000BB">Thread</span><span style="color: #007700">.</span><span style="color: #0000BB">CurrentThread</span><span style="color: #007700">))<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;</span><span style="color: #FF8000">/*&nbsp;Start&nbsp;a&nbsp;monitoring&nbsp;task&nbsp;that&nbsp;may&nbsp;abort&nbsp;the&nbsp;current&nbsp;thread&nbsp;after<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;the&nbsp;specified&nbsp;time&nbsp;limit.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Note&nbsp;that&nbsp;the&nbsp;task&nbsp;will&nbsp;start&nbsp;immediately.&nbsp;Therefore&nbsp;we&nbsp;need&nbsp;to<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;ensure&nbsp;the&nbsp;task&nbsp;does&nbsp;not&nbsp;abort&nbsp;the&nbsp;thread&nbsp;until&nbsp;we&nbsp;entered&nbsp;the<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;try&nbsp;clause;&nbsp;otherwise&nbsp;the&nbsp;ThreadAbortException&nbsp;might&nbsp;fly&nbsp;through<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;the&nbsp;caller&nbsp;of&nbsp;this&nbsp;method.&nbsp;To&nbsp;ensure&nbsp;this,&nbsp;the&nbsp;monitoring&nbsp;task<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;waits&nbsp;until&nbsp;we&nbsp;release&nbsp;the&nbsp;semaphore&nbsp;the&nbsp;first&nbsp;time&nbsp;before<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;actually&nbsp;waiting&nbsp;for&nbsp;the&nbsp;specified&nbsp;time.<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;</span><span style="color: #0000BB">using&nbsp;</span><span style="color: #007700">(var&nbsp;</span><span style="color: #0000BB">monitoringTask&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">Task</span><span style="color: #007700">.</span><span style="color: #0000BB">Run</span><span style="color: #007700">(</span><span style="color: #0000BB">async&nbsp;</span><span style="color: #007700">()&nbsp;=&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">await&nbsp;RunMonitoringTask</span><span style="color: #007700">(</span><span style="color: #0000BB">state</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">timeout</span><span style="color: #007700">)))<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;try<br />&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;</span><span style="color: #0000BB">bool&nbsp;waitForAbortException</span><span style="color: #007700">;<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;try<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;{<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;</span><span style="color: #FF8000">//&nbsp;Allow&nbsp;the&nbsp;monitoring&nbsp;task&nbsp;to&nbsp;begin&nbsp;by&nbsp;releasing&nbsp;the<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;semaphore&nbsp;the&nbsp;first&nbsp;time.<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;Do&nbsp;this&nbsp;in&nbsp;a&nbsp;finally&nbsp;block&nbsp;to&nbsp;ensure&nbsp;if&nbsp;this&nbsp;thread<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;is&nbsp;aborted&nbsp;by&nbsp;other&nbsp;code,&nbsp;the&nbsp;semaphore&nbsp;is&nbsp;still<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;released.<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;</span><span style="color: #007700">try&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;finally<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;{<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;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">state</span><span style="color: #007700">.</span><span style="color: #0000BB">WaitSemaphore</span><span style="color: #007700">.</span><span style="color: #0000BB">Release</span><span style="color: #007700">();<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;}<br /><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;</span><span style="color: #FF8000">//&nbsp;Execute&nbsp;the&nbsp;handler.<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;</span><span style="color: #0000BB">handler</span><span style="color: #007700">();<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;}<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;catch&nbsp;(</span><span style="color: #0000BB">Exception&nbsp;ex</span><span style="color: #007700">)&nbsp;</span><span style="color: #0000BB">when&nbsp;</span><span style="color: #007700">(!(</span><span style="color: #0000BB">ex&nbsp;is&nbsp;ThreadAbortException</span><span style="color: #007700">))<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;{<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;</span><span style="color: #FF8000">/*&nbsp;Need&nbsp;to&nbsp;catch&nbsp;all&nbsp;exceptions&nbsp;(except&nbsp;our&nbsp;own<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;*&nbsp;ThreadAbortException)&nbsp;because&nbsp;we&nbsp;may&nbsp;wait&nbsp;for&nbsp;a<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;*&nbsp;ThreadAbortException&nbsp;to&nbsp;be&nbsp;thrown&nbsp;which&nbsp;is&nbsp;not<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;*&nbsp;possible&nbsp;in&nbsp;a&nbsp;finally&nbsp;handler.<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;*/<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;</span><span style="color: #0000BB">caughtException&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">ExceptionDispatchInfo</span><span style="color: #007700">.</span><span style="color: #0000BB">Capture</span><span style="color: #007700">(</span><span style="color: #0000BB">ex</span><span style="color: #007700">);<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;}<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;finally<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;{<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;</span><span style="color: #FF8000">/*&nbsp;Indicate&nbsp;that&nbsp;the&nbsp;handler&nbsp;is&nbsp;completed,&nbsp;and&nbsp;check<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;*&nbsp;if&nbsp;we&nbsp;need&nbsp;to&nbsp;wait&nbsp;for&nbsp;the&nbsp;ThreadAbortException.<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;*&nbsp;This&nbsp;is&nbsp;done&nbsp;in&nbsp;a&nbsp;finally&nbsp;handler&nbsp;to&nbsp;ensure&nbsp;when<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;*&nbsp;other&nbsp;code&nbsp;wants&nbsp;to&nbsp;abort&nbsp;this&nbsp;thread,&nbsp;the&nbsp;thread<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;*&nbsp;actually&nbsp;will&nbsp;abort&nbsp;as&nbsp;expected&nbsp;but&nbsp;we&nbsp;still&nbsp;can<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;*&nbsp;notify&nbsp;the&nbsp;monitoring&nbsp;task&nbsp;that&nbsp;we&nbsp;already&nbsp;returned.<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;*/<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;</span><span style="color: #0000BB">lock&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">state</span><span style="color: #007700">)<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;{<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;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">state</span><span style="color: #007700">.</span><span style="color: #0000BB">IsExited&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">true</span><span style="color: #007700">;<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;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">waitForAbortException&nbsp;</span><span style="color: #007700">=<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">state</span><span style="color: #007700">.</span><span style="color: #0000BB">AbortState&nbsp;</span><span style="color: #007700">==&nbsp;</span><span style="color: #0000BB">AbortState</span><span style="color: #007700">.</span><span style="color: #0000BB">IsAborting</span><span style="color: #007700">;<br /><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;&nbsp;&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">state</span><span style="color: #007700">.</span><span style="color: #0000BB">AbortState&nbsp;</span><span style="color: #007700">==&nbsp;</span><span style="color: #0000BB">AbortState</span><span style="color: #007700">.</span><span style="color: #0000BB">None</span><span style="color: #007700">)<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;&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;If&nbsp;the&nbsp;monitoring&nbsp;task&nbsp;did&nbsp;not&nbsp;do&nbsp;anything<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;yet,&nbsp;allow&nbsp;it&nbsp;to&nbsp;complete&nbsp;immediately.<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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">state</span><span style="color: #007700">.</span><span style="color: #0000BB">WaitSemaphore</span><span style="color: #007700">.</span><span style="color: #0000BB">Release</span><span style="color: #007700">();<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;&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;}<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;}<br /><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;if&nbsp;(</span><span style="color: #0000BB">waitForAbortException</span><span style="color: #007700">)<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;{<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;</span><span style="color: #FF8000">/*&nbsp;The&nbsp;monitoring&nbsp;task&nbsp;indicated&nbsp;that&nbsp;it&nbsp;will&nbsp;abort&nbsp;our<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;*&nbsp;thread&nbsp;(but&nbsp;the&nbsp;ThreadAbortException&nbsp;did&nbsp;not&nbsp;yet<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;*&nbsp;occur),&nbsp;so&nbsp;we&nbsp;need&nbsp;to&nbsp;wait&nbsp;for&nbsp;the<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;*&nbsp;ThreadAbortException.<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;*&nbsp;This&nbsp;wait&nbsp;is&nbsp;needed&nbsp;because&nbsp;otherwise&nbsp;we&nbsp;may&nbsp;return<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;*&nbsp;too&nbsp;early&nbsp;(and&nbsp;in&nbsp;the&nbsp;finally&nbsp;block&nbsp;we&nbsp;wait&nbsp;for&nbsp;the<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;*&nbsp;monitoring&nbsp;task,&nbsp;causing&nbsp;a&nbsp;deadlock).<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;*/<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;</span><span style="color: #0000BB">Thread</span><span style="color: #007700">.</span><span style="color: #0000BB">Sleep</span><span style="color: #007700">(</span><span style="color: #0000BB">Timeout</span><span style="color: #007700">.</span><span style="color: #0000BB">Infinite</span><span style="color: #007700">);<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;}<br />&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;catch&nbsp;(</span><span style="color: #0000BB">ThreadAbortException&nbsp;ex</span><span style="color: #007700">)<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;</span><span style="color: #0000BB">when&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">ex</span><span style="color: #007700">.</span><span style="color: #0000BB">ExceptionState&nbsp;</span><span style="color: #007700">==&nbsp;</span><span style="color: #0000BB">state</span><span style="color: #007700">)<br />&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;</span><span style="color: #FF8000">//&nbsp;Reset&nbsp;the&nbsp;abort.<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;</span><span style="color: #0000BB">Thread</span><span style="color: #007700">.</span><span style="color: #0000BB">ResetAbort</span><span style="color: #007700">();<br /><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;</span><span style="color: #FF8000">//&nbsp;Indicate&nbsp;that&nbsp;the&nbsp;timeout&nbsp;has&nbsp;been&nbsp;exceeded.<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;</span><span style="color: #007700">throw&nbsp;new&nbsp;</span><span style="color: #0000BB">TimeoutException</span><span style="color: #007700">();<br />&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;finally<br />&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;</span><span style="color: #FF8000">//&nbsp;Wait&nbsp;for&nbsp;the&nbsp;monitoring&nbsp;task&nbsp;to&nbsp;complete.<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;</span><span style="color: #0000BB">monitoringTask</span><span style="color: #007700">.</span><span style="color: #0000BB">Wait</span><span style="color: #007700">();<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;</span><span style="color: #0000BB">currentState&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">;<br />&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;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Check&nbsp;if&nbsp;we&nbsp;need&nbsp;to&nbsp;rethrow&nbsp;a&nbsp;caught&nbsp;exception&nbsp;(preserving&nbsp;the<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;original&nbsp;stacktrace).<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;(</span><span style="color: #0000BB">caughtException&nbsp;</span><span style="color: #007700">!=&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">caughtException</span><span style="color: #007700">.Throw();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;</span><span style="color: #0000BB">async&nbsp;Task&nbsp;RunMonitoringTask</span><span style="color: #007700">(</span><span style="color: #0000BB">HandlerState&nbsp;state</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">int&nbsp;timeout</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Wait&nbsp;until&nbsp;the&nbsp;handler&nbsp;thread&nbsp;entered&nbsp;the&nbsp;try-block.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Use&nbsp;a&nbsp;synchronous&nbsp;wait&nbsp;because&nbsp;we&nbsp;expect&nbsp;this&nbsp;to&nbsp;be&nbsp;a&nbsp;very&nbsp;short<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;period&nbsp;of&nbsp;time.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">state</span><span style="color: #007700">.</span><span style="color: #0000BB">WaitSemaphore</span><span style="color: #007700">.</span><span style="color: #0000BB">Wait</span><span style="color: #007700">();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Now&nbsp;asynchronously&nbsp;wait&nbsp;until&nbsp;the&nbsp;specified&nbsp;time&nbsp;has&nbsp;passed&nbsp;or&nbsp;the<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;semaphore&nbsp;has&nbsp;been&nbsp;released.&nbsp;In&nbsp;the&nbsp;latter&nbsp;case&nbsp;there&nbsp;is&nbsp;no&nbsp;need&nbsp;to<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;call&nbsp;AbortExecution().<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">bool&nbsp;completed&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">await&nbsp;state</span><span style="color: #007700">.</span><span style="color: #0000BB">WaitSemaphore</span><span style="color: #007700">.</span><span style="color: #0000BB">WaitAsync</span><span style="color: #007700">(</span><span style="color: #0000BB">timeout</span><span style="color: #007700">);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Abort&nbsp;the&nbsp;handler&nbsp;thread.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">if&nbsp;(!</span><span style="color: #0000BB">completed</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">AbortExecution</span><span style="color: #007700">(</span><span style="color: #0000BB">state</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;</span><span style="color: #0000BB">void&nbsp;AbortExecution</span><span style="color: #007700">(</span><span style="color: #0000BB">HandlerState&nbsp;state</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">bool&nbsp;canAbort</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">lock&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">state</span><span style="color: #007700">)<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;if&nbsp;(</span><span style="color: #0000BB">state</span><span style="color: #007700">.</span><span style="color: #0000BB">IsExited</span><span style="color: #007700">)<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;</span><span style="color: #FF8000">//&nbsp;The&nbsp;handler&nbsp;has&nbsp;already&nbsp;exited.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">return;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;Check&nbsp;if&nbsp;we&nbsp;can&nbsp;call&nbsp;Thread.Abort()&nbsp;or&nbsp;if&nbsp;the&nbsp;handler&nbsp;thread&nbsp;is<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;currently&nbsp;in&nbsp;a&nbsp;critical&nbsp;section&nbsp;and&nbsp;needs&nbsp;to&nbsp;abort&nbsp;himself&nbsp;when<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;leaving&nbsp;the&nbsp;critical&nbsp;section.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">canAbort&nbsp;</span><span style="color: #007700">=&nbsp;!</span><span style="color: #0000BB">state</span><span style="color: #007700">.</span><span style="color: #0000BB">IsCriticalSection</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">state</span><span style="color: #007700">.</span><span style="color: #0000BB">AbortState&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">canAbort&nbsp;</span><span style="color: #007700">?&nbsp;</span><span style="color: #0000BB">AbortState</span><span style="color: #007700">.</span><span style="color: #0000BB">IsAborting<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">AbortState</span><span style="color: #007700">.</span><span style="color: #0000BB">ShouldAbort</span><span style="color: #007700">;<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;if&nbsp;(</span><span style="color: #0000BB">canAbort</span><span style="color: #007700">)<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;</span><span style="color: #FF8000">/*&nbsp;The&nbsp;handler&nbsp;thread&nbsp;is&nbsp;not&nbsp;in&nbsp;a&nbsp;critical&nbsp;section&nbsp;so&nbsp;we&nbsp;can<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;directly&nbsp;abort&nbsp;it.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;This&nbsp;needs&nbsp;to&nbsp;be&nbsp;done&nbsp;outside&nbsp;of&nbsp;the&nbsp;lock&nbsp;because&nbsp;Abort()&nbsp;could<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;block&nbsp;if&nbsp;the&nbsp;&nbsp;thread&nbsp;is&nbsp;currently&nbsp;in&nbsp;a&nbsp;finally&nbsp;handler&nbsp;(and<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;trying&nbsp;to&nbsp;lock&nbsp;on&nbsp;the&nbsp;state&nbsp;object),&nbsp;which&nbsp;could&nbsp;lead&nbsp;to&nbsp;a<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;deadlock.<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;</span><span style="color: #0000BB">state</span><span style="color: #007700">.</span><span style="color: #0000BB">HandlerThread</span><span style="color: #007700">.</span><span style="color: #0000BB">Abort</span><span style="color: #007700">(</span><span style="color: #0000BB">state</span><span style="color: #007700">);<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;</span><span style="color: #FF8000">///&nbsp;&lt;summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Notifies&nbsp;this&nbsp;class&nbsp;that&nbsp;the&nbsp;handler&nbsp;thread&nbsp;is&nbsp;entering&nbsp;a&nbsp;critical<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;section&nbsp;in&nbsp;which&nbsp;aborting&nbsp;the&nbsp;thread&nbsp;could&nbsp;corrupt&nbsp;the&nbsp;system's&nbsp;state.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;This&nbsp;means&nbsp;aborting&nbsp;the&nbsp;thread&nbsp;will&nbsp;be&nbsp;deferred&nbsp;until&nbsp;leaving&nbsp;the<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;critical&nbsp;section.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Note&nbsp;that&nbsp;you&nbsp;must&nbsp;call&nbsp;&lt;see&nbsp;cref="ExitCriticalSection"/&gt;&nbsp;in&nbsp;a<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;c&gt;finally&lt;/c&gt;&nbsp;block&nbsp;once&nbsp;the&nbsp;thread&nbsp;left&nbsp;the&nbsp;critical&nbsp;section.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;</span><span style="color: #0000BB">void&nbsp;EnterCriticalSection</span><span style="color: #007700">()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">currentState&nbsp;</span><span style="color: #007700">==&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;</span><span style="color: #0000BB">InvalidOperationException</span><span style="color: #007700">();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">bool&nbsp;waitForAbortException</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">lock&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">currentState</span><span style="color: #007700">)<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;if&nbsp;(</span><span style="color: #0000BB">Thread</span><span style="color: #007700">.</span><span style="color: #0000BB">CurrentThread&nbsp;</span><span style="color: #007700">!=&nbsp;</span><span style="color: #0000BB">currentState</span><span style="color: #007700">.</span><span style="color: #0000BB">HandlerThread<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">||&nbsp;</span><span style="color: #0000BB">currentState</span><span style="color: #007700">.</span><span style="color: #0000BB">IsCriticalSection</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;</span><span style="color: #0000BB">InvalidOperationException</span><span style="color: #007700">();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">currentState</span><span style="color: #007700">.</span><span style="color: #0000BB">IsCriticalSection&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">true</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">waitForAbortException&nbsp;</span><span style="color: #007700">=<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">currentState</span><span style="color: #007700">.</span><span style="color: #0000BB">AbortState&nbsp;</span><span style="color: #007700">==&nbsp;</span><span style="color: #0000BB">AbortState</span><span style="color: #007700">.</span><span style="color: #0000BB">IsAborting</span><span style="color: #007700">;<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;if&nbsp;(</span><span style="color: #0000BB">waitForAbortException</span><span style="color: #007700">)<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;</span><span style="color: #FF8000">//&nbsp;The&nbsp;monitoring&nbsp;task&nbsp;indicated&nbsp;that&nbsp;it&nbsp;will&nbsp;abort&nbsp;our&nbsp;thread,&nbsp;so<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;we&nbsp;need&nbsp;to&nbsp;wait&nbsp;for&nbsp;the&nbsp;ThreadAbortException.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Thread</span><span style="color: #007700">.</span><span style="color: #0000BB">Sleep</span><span style="color: #007700">(</span><span style="color: #0000BB">Timeout</span><span style="color: #007700">.</span><span style="color: #0000BB">Infinite</span><span style="color: #007700">);<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;public&nbsp;</span><span style="color: #0000BB">void&nbsp;ExitCriticalSection</span><span style="color: #007700">()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(</span><span style="color: #0000BB">currentState&nbsp;</span><span style="color: #007700">==&nbsp;</span><span style="color: #0000BB">null</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;</span><span style="color: #0000BB">InvalidOperationException</span><span style="color: #007700">();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">bool&nbsp;shouldAbort</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">lock&nbsp;</span><span style="color: #007700">(</span><span style="color: #0000BB">currentState</span><span style="color: #007700">)<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;if&nbsp;(</span><span style="color: #0000BB">Thread</span><span style="color: #007700">.</span><span style="color: #0000BB">CurrentThread&nbsp;</span><span style="color: #007700">!=&nbsp;</span><span style="color: #0000BB">currentState</span><span style="color: #007700">.</span><span style="color: #0000BB">HandlerThread<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">||&nbsp;!</span><span style="color: #0000BB">currentState</span><span style="color: #007700">.</span><span style="color: #0000BB">IsCriticalSection</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;</span><span style="color: #0000BB">InvalidOperationException</span><span style="color: #007700">();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">currentState</span><span style="color: #007700">.</span><span style="color: #0000BB">IsCriticalSection&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">false</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">shouldAbort&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">currentState</span><span style="color: #007700">.</span><span style="color: #0000BB">AbortState&nbsp;</span><span style="color: #007700">==&nbsp;</span><span style="color: #0000BB">AbortState</span><span style="color: #007700">.</span><span style="color: #0000BB">ShouldAbort</span><span style="color: #007700">;<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;if&nbsp;(</span><span style="color: #0000BB">shouldAbort</span><span style="color: #007700">)<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;</span><span style="color: #FF8000">//&nbsp;The&nbsp;monitoring&nbsp;task&nbsp;indicated&nbsp;that&nbsp;it&nbsp;wanted&nbsp;to&nbsp;abort&nbsp;our<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;thread&nbsp;while&nbsp;we&nbsp;were&nbsp;in&nbsp;a&nbsp;critical&nbsp;section,&nbsp;so&nbsp;we&nbsp;need&nbsp;to&nbsp;abort<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;ourselves.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">Thread</span><span style="color: #007700">.</span><span style="color: #0000BB">CurrentThread</span><span style="color: #007700">.</span><span style="color: #0000BB">Abort</span><span style="color: #007700">(</span><span style="color: #0000BB">currentState</span><span style="color: #007700">);<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&nbsp;</span><span style="color: #0000BB">enum&nbsp;AbortState<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">///&nbsp;&lt;summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Indicates&nbsp;that&nbsp;the&nbsp;monitoring&nbsp;task&nbsp;has&nbsp;not&nbsp;yet&nbsp;done&nbsp;any&nbsp;action.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">None&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">0</span><span style="color: #007700">,<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">///&nbsp;&lt;summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Indicates&nbsp;that&nbsp;the&nbsp;monitoring&nbsp;task&nbsp;is&nbsp;about&nbsp;to&nbsp;abort&nbsp;the&nbsp;handler<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;thread.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">IsAborting&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">1</span><span style="color: #007700">,<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">///&nbsp;&lt;summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Indicates&nbsp;that&nbsp;the&nbsp;monitoring&nbsp;task&nbsp;wanted&nbsp;to&nbsp;abort&nbsp;the&nbsp;handler<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;thread&nbsp;but&nbsp;the&nbsp;handler&nbsp;thread&nbsp;was&nbsp;in&nbsp;a&nbsp;critical&nbsp;section,&nbsp;and&nbsp;needs<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;to&nbsp;abort&nbsp;itself&nbsp;when&nbsp;leaving&nbsp;the&nbsp;critical&nbsp;section.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">ShouldAbort&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">2<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;class&nbsp;</span><span style="color: #0000BB">HandlerState&nbsp;</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">IDisposable<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">{<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">Thread&nbsp;HandlerThread&nbsp;</span><span style="color: #007700">{&nbsp;</span><span style="color: #0000BB">get</span><span style="color: #007700">;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">SemaphoreSlim&nbsp;WaitSemaphore&nbsp;</span><span style="color: #007700">{&nbsp;</span><span style="color: #0000BB">get</span><span style="color: #007700">;&nbsp;}&nbsp;=&nbsp;new&nbsp;</span><span style="color: #0000BB">SemaphoreSlim</span><span style="color: #007700">(</span><span style="color: #0000BB">0</span><span style="color: #007700">);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">bool&nbsp;IsCriticalSection&nbsp;</span><span style="color: #007700">{&nbsp;</span><span style="color: #0000BB">get</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">set</span><span style="color: #007700">;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">///&nbsp;&lt;summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Indicates&nbsp;if&nbsp;the&nbsp;handler&nbsp;is&nbsp;already&nbsp;completed&nbsp;(so&nbsp;there's&nbsp;no&nbsp;need<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;to&nbsp;abort&nbsp;the&nbsp;thread).<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;This&nbsp;flag&nbsp;is&nbsp;set&nbsp;by&nbsp;the&nbsp;handler&nbsp;thread.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;</span><span style="color: #0000BB">bool&nbsp;IsExited&nbsp;</span><span style="color: #007700">{&nbsp;</span><span style="color: #0000BB">get</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">set</span><span style="color: #007700">;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">///&nbsp;&lt;summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Indicates&nbsp;that&nbsp;the&nbsp;wait&nbsp;task&nbsp;wanted&nbsp;to&nbsp;abort&nbsp;the&nbsp;handler&nbsp;thread&nbsp;but<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;the&nbsp;handler&nbsp;thread&nbsp;was&nbsp;in&nbsp;a&nbsp;critical&nbsp;section,&nbsp;and&nbsp;needs&nbsp;to&nbsp;abort<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;itself&nbsp;when&nbsp;leaving&nbsp;the&nbsp;critical&nbsp;section.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;This&nbsp;flag&nbsp;is&nbsp;set&nbsp;by&nbsp;the&nbsp;wait&nbsp;task.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #007700">public&nbsp;</span><span style="color: #0000BB">AbortState&nbsp;AbortState&nbsp;</span><span style="color: #007700">{&nbsp;</span><span style="color: #0000BB">get</span><span style="color: #007700">;&nbsp;</span><span style="color: #0000BB">set</span><span style="color: #007700">;&nbsp;}<br /><br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">HandlerState</span><span style="color: #007700">(</span><span style="color: #0000BB">Thread&nbsp;handlerThread</span><span style="color: #007700">)<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;</span><span style="color: #0000BB">this</span><span style="color: #007700">.</span><span style="color: #0000BB">HandlerThread&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">handlerThread</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~</span><span style="color: #0000BB">HandlerState</span><span style="color: #007700">()<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;</span><span style="color: #0000BB">Dispose</span><span style="color: #007700">(</span><span style="color: #0000BB">false</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">void&nbsp;Dispose</span><span style="color: #007700">()<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;</span><span style="color: #0000BB">Dispose</span><span style="color: #007700">(</span><span style="color: #0000BB">true</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">GC</span><span style="color: #007700">.</span><span style="color: #0000BB">SuppressFinalize</span><span style="color: #007700">(</span><span style="color: #0000BB">this</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;</span><span style="color: #0000BB">void&nbsp;Dispose</span><span style="color: #007700">(</span><span style="color: #0000BB">bool&nbsp;disposing</span><span style="color: #007700">)<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;if&nbsp;(</span><span style="color: #0000BB">disposing</span><span style="color: #007700">)<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;</span><span style="color: #0000BB">WaitSemaphore</span><span style="color: #007700">.</span><span style="color: #0000BB">Dispose</span><span style="color: #007700">();<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 />}&nbsp;</span><br />
</span><br />
</code></div><br />
<br />
原来执行javascpript的方式如下：<br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_RwC7sdjwRXeu')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_RwC7sdjwRXeu);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_RwC7sdjwRXeu" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #007700">var&nbsp;</span><span style="color: #0000BB">engine&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">ScriptEngine</span><span style="color: #007700">();<br />var&nbsp;</span><span style="color: #0000BB">compiledScript&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">engine</span><span style="color: #007700">.</span><span style="color: #0000BB">Compile</span><span style="color: #007700">(new&nbsp;</span><span style="color: #0000BB">StringScriptSource</span><span style="color: #007700">(<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #DD0000">"while&nbsp;(true)&nbsp;;"</span><span style="color: #007700">));<br /></span><span style="color: #0000BB">compiledScript</span><span style="color: #007700">.</span><span style="color: #0000BB">Execute</span><span style="color: #007700">();&nbsp;</span><br />
</span><br />
</code></div><br />
<br />
<h2>改进后新的执行javascpript的方式如下：</h2><br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_mEPqsCmEtuQB')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_mEPqsCmEtuQB);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_mEPqsCmEtuQB" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #007700">var&nbsp;</span><span style="color: #0000BB">timeoutHelper&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">ScriptTimeoutHelper</span><span style="color: #007700">();<br />var&nbsp;</span><span style="color: #0000BB">engine&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">ScriptEngine</span><span style="color: #007700">();<br />var&nbsp;</span><span style="color: #0000BB">compiledScript&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">engine</span><span style="color: #007700">.</span><span style="color: #0000BB">Compile</span><span style="color: #007700">(new&nbsp;</span><span style="color: #0000BB">StringScriptSource</span><span style="color: #007700">(<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #DD0000">"while&nbsp;(true)&nbsp;;"</span><span style="color: #007700">));<br />try{<br /></span><span style="color: #0000BB">timeoutHelper</span><span style="color: #007700">.</span><span style="color: #0000BB">RunWithTimeout</span><span style="color: #007700">(()&nbsp;=&gt;&nbsp;</span><span style="color: #0000BB">compiledScript</span><span style="color: #007700">.</span><span style="color: #0000BB">Execute</span><span style="color: #007700">(),&nbsp;</span><span style="color: #0000BB">1000</span><span style="color: #007700">);<br />}<br />catch(</span><span style="color: #0000BB">TimeoutException&nbsp;ex</span><span style="color: #007700">){<br /></span><span style="color: #FF8000">//这里表示执行超时<br /></span><span style="color: #007700">}<br />&nbsp;</span><br />
</span><br />
</code></div><br />
<br />
<h2>注意事项：</h2><br />
<div class="txt_main">我们使用useScriptEngine.Compile()首先编译脚本，然后将超时仅应用于实际执行脚本。<br />
上面的调用代码设置的超时时间是1秒，如果JavaScript未在1秒钟内完成，我们将捕获到TimeoutException异常。<br />
<br />
<br />
<strong>注：在发生TimeoutException以后，我们不应该继续使用ScriptEngine及其关联的对象实例，因为它们可能处于不一致/不可用状态。而是创建一个新的ScriptEngine实例以运行更多脚本文件。</strong><br />
<br />
</div>]]></content:encoded>
<link>https://www.rickw.cn/blogview/283</link>
<dc:subject>C# .Net编程</dc:subject>
<dc:creator>rick</dc:creator>
<dc:date>2023-12-01 23:12:13</dc:date>
</item>
		
<item rdf:about="https://www.rickw.cn/blogview/279">
<title><![CDATA[介绍一个C#的javascpript引擎 Jurassic]]></title>
	
<description><![CDATA[这是一个纯.Net实现的javascpript引擎，目前支持ECMAScript&nbsp;3&nbsp;和&nbsp;ECMAScript&nbsp;5&nbsp;包括&nbsp;ES5&nbsp;strict&nbsp;模式。<br />
ECMAScript&nbsp;6的支持还在开发中，已经支持了es6的大部分特性。<br />
<br />
性能好：它将JavaScript编译为.NET字节码（CIL），而非解释执行。这样使得它的运行性能更好；<br />
<br />]]></description>
<content:encoded><![CDATA[这是一个纯.Net实现的javascpript引擎，目前支持ECMAScript&nbsp;3&nbsp;和&nbsp;ECMAScript&nbsp;5&nbsp;包括&nbsp;ES5&nbsp;strict&nbsp;模式。<br />
ECMAScript&nbsp;6的支持还在开发中，已经支持了es6的大部分特性。<br />
<br />
性能好：它将JavaScript编译为.NET字节码（CIL），而非解释执行。这样使得它的运行性能更好；<br />
<br />
纯.Net开发：纯.Net开发，不依赖任何第三方库，只有单个dll文件，可以完全集成到.Net框架中，可以在任何支持.Net平台执行；<br />
<br />
使用：<br />
1，可以直接用&nbsp;NuGet&nbsp;获取&nbsp;Jurassic。<br />
<div class="txt_main">using&nbsp;Jurassic;</div><br />
简单的执行js字符串<br />
<div class="txt_main">var&nbsp;engine&nbsp;=&nbsp;new&nbsp;Jurassic.ScriptEngine();<br />
&nbsp;engine.Evaluate("function&nbsp;main(a,b){return&nbsp;a+b;}");<br />
var&nbsp;addResult=&nbsp;engine.CallGlobalFunction("main",&nbsp;5,&nbsp;6);//结果11<br />
</div><br />
<br />
2，.Net&nbsp;和&nbsp;javascpript&nbsp;之间交互。<br />
<div class="txt_main"><strong>暴露net的class给js</strong><br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_ABiAnVKdbdJq')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_ABiAnVKdbdJq);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_ABiAnVKdbdJq" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #0000BB"><br />using&nbsp;Jurassic</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">using&nbsp;Jurassic</span><span style="color: #007700">.</span><span style="color: #0000BB">Library</span><span style="color: #007700">;<br /><br />public&nbsp;class&nbsp;</span><span style="color: #0000BB">AppInfo&nbsp;</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">ObjectInstance<br /></span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">AppInfo</span><span style="color: #007700">(</span><span style="color: #0000BB">ScriptEngine&nbsp;engine</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;</span><span style="color: #0000BB">base</span><span style="color: #007700">(</span><span style="color: #0000BB">engine</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;重写name属性<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">this</span><span style="color: #007700">[</span><span style="color: #DD0000">"name"</span><span style="color: #007700">]&nbsp;=&nbsp;</span><span style="color: #DD0000">"Test&nbsp;Application"</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #FF8000">//&nbsp;只读属性<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">this</span><span style="color: #007700">.</span><span style="color: #0000BB">DefineProperty</span><span style="color: #007700">(</span><span style="color: #DD0000">"version"</span><span style="color: #007700">,&nbsp;new&nbsp;</span><span style="color: #0000BB">PropertyDescriptor</span><span style="color: #007700">(</span><span style="color: #0000BB">5</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">PropertyAttributes</span><span style="color: #007700">.</span><span style="color: #0000BB">Sealed</span><span style="color: #007700">),&nbsp;</span><span style="color: #0000BB">true</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br />&nbsp;<br /></span><span style="color: #0000BB">engine</span><span style="color: #007700">.</span><span style="color: #0000BB">SetGlobalValue</span><span style="color: #007700">(</span><span style="color: #DD0000">"appInfo"</span><span style="color: #007700">,&nbsp;new&nbsp;</span><span style="color: #0000BB">AppInfo</span><span style="color: #007700">(</span><span style="color: #0000BB">engine</span><span style="color: #007700">));<br /></span><span style="color: #0000BB">Console</span><span style="color: #007700">.</span><span style="color: #0000BB">WriteLine</span><span style="color: #007700">(</span><span style="color: #0000BB">engine</span><span style="color: #007700">.</span><span style="color: #0000BB">Evaluate</span><span style="color: #007700">&lt;</span><span style="color: #0000BB">string</span><span style="color: #007700">&gt;(</span><span style="color: #DD0000">"appInfo.name&nbsp;+&nbsp;'&nbsp;'&nbsp;+&nbsp;appInfo.version"</span><span style="color: #007700">));&nbsp;</span><br />
</span><br />
</code></div><br />
<br />
<strong>暴露net的class的静态方法</strong><br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_5KNL2dAgBOZ9')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_5KNL2dAgBOZ9);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_5KNL2dAgBOZ9" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #0000BB"><br />using&nbsp;Jurassic</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">using&nbsp;Jurassic</span><span style="color: #007700">.</span><span style="color: #0000BB">Library</span><span style="color: #007700">;<br /><br />public&nbsp;class&nbsp;</span><span style="color: #0000BB">Math2&nbsp;</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">ObjectInstance<br /></span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">Math2</span><span style="color: #007700">(</span><span style="color: #0000BB">ScriptEngine&nbsp;engine</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;</span><span style="color: #0000BB">base</span><span style="color: #007700">(</span><span style="color: #0000BB">engine</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">this</span><span style="color: #007700">.</span><span style="color: #0000BB">PopulateFunctions</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style="color: #0000BB">JSFunction</span><span style="color: #007700">(</span><span style="color: #0000BB">Name&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"log10"</span><span style="color: #007700">)]<br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;</span><span style="color: #0000BB">double&nbsp;Log10</span><span style="color: #007700">(</span><span style="color: #0000BB">double&nbsp;num</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span style="color: #0000BB">Math</span><span style="color: #007700">.</span><span style="color: #0000BB">Log10</span><span style="color: #007700">(</span><span style="color: #0000BB">num</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br />&nbsp;<br /></span><span style="color: #0000BB">engine</span><span style="color: #007700">.</span><span style="color: #0000BB">SetGlobalValue</span><span style="color: #007700">(</span><span style="color: #DD0000">"math2"</span><span style="color: #007700">,&nbsp;new&nbsp;</span><span style="color: #0000BB">Math2</span><span style="color: #007700">(</span><span style="color: #0000BB">engine</span><span style="color: #007700">));<br /></span><span style="color: #0000BB">engine</span><span style="color: #007700">.</span><span style="color: #0000BB">Evaluate</span><span style="color: #007700">&lt;</span><span style="color: #0000BB">double</span><span style="color: #007700">&gt;(</span><span style="color: #DD0000">"math2.log10(1000)"</span><span style="color: #007700">);&nbsp;</span><br />
</span><br />
</code></div><br />
<br />
<strong>暴露net的类实例</strong><br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_5DmlxZIyD9iT')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_5DmlxZIyD9iT);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_5DmlxZIyD9iT" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #0000BB"><br />using&nbsp;Jurassic</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">using&nbsp;Jurassic</span><span style="color: #007700">.</span><span style="color: #0000BB">Library</span><span style="color: #007700">;<br /><br />public&nbsp;class&nbsp;</span><span style="color: #0000BB">RandomConstructor&nbsp;</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">ClrFunction<br /></span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">RandomConstructor</span><span style="color: #007700">(</span><span style="color: #0000BB">ScriptEngine&nbsp;engine</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;</span><span style="color: #0000BB">base</span><span style="color: #007700">(</span><span style="color: #0000BB">engine</span><span style="color: #007700">.Function.</span><span style="color: #0000BB">InstancePrototype</span><span style="color: #007700">,&nbsp;</span><span style="color: #DD0000">"Random"</span><span style="color: #007700">,&nbsp;new&nbsp;</span><span style="color: #0000BB">RandomInstance</span><span style="color: #007700">(</span><span style="color: #0000BB">engine</span><span style="color: #007700">.</span><span style="color: #0000BB">Object</span><span style="color: #007700">.</span><span style="color: #0000BB">InstancePrototype</span><span style="color: #007700">))<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style="color: #0000BB">JSConstructorFunction</span><span style="color: #007700">]<br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">RandomInstance&nbsp;Construct</span><span style="color: #007700">(</span><span style="color: #0000BB">int&nbsp;seed</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;</span><span style="color: #0000BB">RandomInstance</span><span style="color: #007700">(</span><span style="color: #0000BB">this</span><span style="color: #007700">.</span><span style="color: #0000BB">InstancePrototype</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">seed</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br />public&nbsp;class&nbsp;</span><span style="color: #0000BB">RandomInstance&nbsp;</span><span style="color: #007700">:&nbsp;</span><span style="color: #0000BB">ObjectInstance<br /></span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;</span><span style="color: #0000BB">Random&nbsp;random</span><span style="color: #007700">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">RandomInstance</span><span style="color: #007700">(</span><span style="color: #0000BB">ObjectInstance&nbsp;prototype</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;</span><span style="color: #0000BB">base</span><span style="color: #007700">(</span><span style="color: #0000BB">prototype</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">this</span><span style="color: #007700">.</span><span style="color: #0000BB">PopulateFunctions</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">this</span><span style="color: #007700">.</span><span style="color: #0000BB">random&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Random</span><span style="color: #007700">(</span><span style="color: #0000BB">0</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">RandomInstance</span><span style="color: #007700">(</span><span style="color: #0000BB">ObjectInstance&nbsp;prototype</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">int&nbsp;seed</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;</span><span style="color: #0000BB">base</span><span style="color: #007700">(</span><span style="color: #0000BB">prototype</span><span style="color: #007700">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">this</span><span style="color: #007700">.</span><span style="color: #0000BB">random&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">Random</span><span style="color: #007700">(</span><span style="color: #0000BB">seed</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;[</span><span style="color: #0000BB">JSFunction</span><span style="color: #007700">(</span><span style="color: #0000BB">Name&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"nextDouble"</span><span style="color: #007700">)]<br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;</span><span style="color: #0000BB">double&nbsp;NextDouble</span><span style="color: #007700">()<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;</span><span style="color: #0000BB">this</span><span style="color: #007700">.</span><span style="color: #0000BB">random</span><span style="color: #007700">.</span><span style="color: #0000BB">NextDouble</span><span style="color: #007700">();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br />&nbsp;<br />&nbsp;<br /></span><span style="color: #0000BB">engine</span><span style="color: #007700">.</span><span style="color: #0000BB">SetGlobalValue</span><span style="color: #007700">(</span><span style="color: #DD0000">"Random"</span><span style="color: #007700">,&nbsp;new&nbsp;</span><span style="color: #0000BB">RandomConstructor</span><span style="color: #007700">(</span><span style="color: #0000BB">engine</span><span style="color: #007700">));<br /></span><span style="color: #0000BB">engine</span><span style="color: #007700">.</span><span style="color: #0000BB">Evaluate</span><span style="color: #007700">&lt;</span><span style="color: #0000BB">double</span><span style="color: #007700">&gt;(</span><span style="color: #DD0000">"var&nbsp;rand&nbsp;=&nbsp;new&nbsp;Random(1000);&nbsp;rand.nextDouble()"</span><span style="color: #007700">);&nbsp;</span><br />
</span><br />
</code></div><br />
</div>]]></content:encoded>
<link>https://www.rickw.cn/blogview/279</link>
<dc:subject>C# .Net编程</dc:subject>
<dc:creator>rick</dc:creator>
<dc:date>2023-11-30 14:25:34</dc:date>
</item>
		
<item rdf:about="https://www.rickw.cn/blogview/277">
<title><![CDATA[C#等效于php的password_verify 和 password_hash 功能的函数实现]]></title>
	
<description><![CDATA[<div class="txt_main">C#中能够等价于&nbsp;php&nbsp;password_verify&nbsp;和&nbsp;password_hash&nbsp;功能的实现方法。<br />
有时候可能会需要在C#程序中来验证&nbsp;php&nbsp;生成的哈希密码。实现php系统和C#系统的密码互通。<br />
例如：将php系统迁移到&nbsp;.NetCore的系统。<br />
或者混合使用php系统和.NetCore系统。</div><br />
<br />]]></description>
<content:encoded><![CDATA[<div class="txt_main">C#中能够等价于&nbsp;php&nbsp;password_verify&nbsp;和&nbsp;password_hash&nbsp;功能的实现方法。<br />
有时候可能会需要在C#程序中来验证&nbsp;php&nbsp;生成的哈希密码。实现php系统和C#系统的密码互通。<br />
例如：将php系统迁移到&nbsp;.NetCore的系统。<br />
或者混合使用php系统和.NetCore系统。</div><br />
<br />
<h2>一种保底的实现，间接方式</h2><br />
<div class="txt_main">使用php开发一个api接口，公开给C#调用。</div><br />
<br />
<h2>直接C#实现的方式</h2><br />
<div class="txt_main">php的&nbsp;password_hash&nbsp;使用的是Blowfish加密算法。我们避免重复造轮子，可以利用现成的类库【CryptSharp】。<br />
<strong>C#中实现的验证密码代码如下：</strong><br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_JxcXiiViOm2e')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_JxcXiiViOm2e);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_JxcXiiViOm2e" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #0000BB">using&nbsp;CryptSharp</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">//等价于PHP的&nbsp;password_verify&nbsp;函数<br />//&nbsp;验证密码是正确<br />//&nbsp;inputPassword&nbsp;用户输入的密码<br />//&nbsp;hashcryptedPassword&nbsp;PHP的password_hash哈希加密的密码<br />//<br /></span><span style="color: #0000BB">bool&nbsp;isOK&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">Crypter</span><span style="color: #007700">.</span><span style="color: #0000BB">CheckPassword</span><span style="color: #007700">(</span><span style="color: #0000BB">inputPassword</span><span style="color: #007700">,&nbsp;</span><span style="color: #0000BB">hashcryptedPassword</span><span style="color: #007700">);<br />&nbsp;</span><br />
</span><br />
</code></div><br />
<br />
<strong>当然我们也可以在C#中实现PHP&nbsp;password_hash&nbsp;等效的加密功能：</strong><br />
<script type="text/javascript">window.attachEvent("onload",function (){AutoSizeDIV('CODE_POSqTx3DwrLZ')})</script><table width="98%" border="0" align="center" cellpadding="0" cellspacing="0" class="code_head"><tr><td></td><td align="right"><a href="javascript:CopyText(document.all.CODE_POSqTx3DwrLZ);">[复制到剪贴板] </a></td></tr></table><div class="code_main" id="CODE_POSqTx3DwrLZ" style="overflow-y:auto;overflow-x:auto;width: 98%;min-height:40px;max-height:500px;"><code><span style="color: #000000"><br />
<span style="color: #0000BB">using&nbsp;CryptSharp</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">//等效于PHP的&nbsp;password_hash&nbsp;函数<br />//&nbsp;和PHP使用相同的加密算法：&nbsp;Blowfish&nbsp;crypt&nbsp;("BCrypt")&nbsp;<br />//<br /></span><span style="color: #0000BB">string&nbsp;hashcryptedPassword&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #0000BB">Crypter</span><span style="color: #007700">.</span><span style="color: #0000BB">Blowfish</span><span style="color: #007700">.</span><span style="color: #0000BB">Crypt</span><span style="color: #007700">(</span><span style="color: #0000BB">password</span><span style="color: #007700">);<br />&nbsp;</span><br />
</span><br />
</code></div><br />
</div><br />
<br />
<h2>类库【CryptSharp】下载</h2><br />
<img src="/images/download.gif" align="absmiddle" /><a target="_blank" href="http://dl.rickw.cn/f/20272120-983481994-5d0dbe">C#加密库CryptSharp_2_1_0.zip</a><br />
]]></content:encoded>
<link>https://www.rickw.cn/blogview/277</link>
<dc:subject>C# .Net编程</dc:subject>
<dc:creator>rick</dc:creator>
<dc:date>2023-11-29 11:19:37</dc:date>
</item>
		
</rdf:Seq>
</items>
</channel>
</rdf:RDF>