C# 多线程操作整理 (System.Threading)

Thread 类

创建并控制线程,设置其优先级并获取其状态。

命名空间:System.Threading 程序集:mscorlib(在 mscorlib.dll 中)

概述与概念

C#支持通过多线程并行地执行代码,一个线程有它独立的执行路径,能够与其它的线程同时地运行。一个C#程序开始于一个单线程,这个单线程是被CLR和操作系统(也称为“主线程”)自动创建的,并具有多线程创建额外的线程。

1.使用线程的情况

  • ①.程序需要执行和两个和多个任务
  • ②.程序要等待某事件的发生:例如用户输入、文件操作、网络操作和搜索
  • ③.后台程序

2.多线程的并发执行 如果有多个线程在执行,单CPU只有一个,到底执行的哪个?

  • ①.如果一个线程连续占用CPU资源时间过长,其它的资源得不到执行,      则系统会强制的切换执行其它线程。(强制剥夺)
  • ②.如果一个线程没事可做、CPU可执行其它线程。(主动放弃)
  • ③.这是由操作系统的调度机制决定的,不同的操作系统调度机制不一样。    一般无法精确的预料多线程的执行顺序,在程序设计的时候应特别注意

3.创建并启动线程

ThreadStart 线程启动委托名=new ThreadStart(方法名);

Thread 线程实例名=new Thread(线程启动委托名); 线程实例名.Start();

4.终止线程

  • ①.线程实例名.Abort();用此方法的后果是不可恢复的终止线程。
  • ②.线程实例名.Interrupt();中断后可恢复

5.休眠线程

  • ①.线程实例名.Sleep();     当线程Sleep时,系统就立即退出执行队列一段时间,当睡眠结束时,系统会产生一个时钟中断,从而     使线程回到执行队列中,从而恢复线程的执行。

6.挂起/恢复线程

  • ①.线程实例名.Suspend();挂起     与线程休眠不同,线程的挂起不会使线程立即停止执行,直到线程到达安全点之后它才可以将该线程挂起,如果线程尚未启动或已经停止,则它将不能挂起。
  • ②.线程实例名.Resume();恢复      将使一个线程跳出挂起状态并使该线程继续执行。     一个线程不能对另一个线程调用Sleep() ,但是一个线程可以对另一个线程调用Suspend()。     还可以使用许多其它的方式来阻塞线程。例如,可以通过调用 Thread.Join 使一个线程等待另一个线程 (子线程)停止。使用Monitor.Wait使一个线程等待访问一个同步对象。

7.串行化线程

  • ①.线程实例名.jion();     例如在主线程中插入t.jion();      主线程执行到这条语句后,主线程(当前线程)立即进入阻塞状态.直到t运行完后阻塞状态才解除。相当于把t的任务插入或串联到主线程中,把两条线索串联成一条线索

8.线程的锁定机制 线程的锁定机制可以保证每次只有一个线程可以访问共享资源。 使用关键字lock

  • ①.lock语句的语法      lock(对象引用)语句块;
  • ②.lock语句的功能      当对象被lock 锁定时,访问该线程的其它线程会进入等待的状态。
  • ③.对象锁机制保证了对象访问的完整性:只有一个线程完成操作后,其它的线程才能进行操作。
  • ④.一般情况下,当一个线程写某个变量,而同时可能有其它的线程读或写这个变量时,为了保持数据的一 致性应该使用锁定机制。
  • ⑤.线程的安全性      线程安全性就是保护的类的成员和代码的安全,从而使他们不会同时被几个线程中断,使用锁定机制。
  • ⑥.多线程公用一个对象时,就不应该使用lock关键字了,这里Monitor,Monitor提供了使线程共享资源的方 案。 Monitor类可以锁定一个对象,一个线程只有得到这把锁才可以对该对象进行操作。 如: Monitor.Enter(obj);
    Monitor.Exit(obj);
  • ⑦.临界区和锁 当谈论多线程应用程序的时候,首先应该想到的就是并发性问题。尽管这对于同时执行多个任务的程序是很有用的,但通常都是危险的。为了解决这个问题,在C#中提出了临界区和锁的概念。在程序设计中,临界区是一块在任何时候只能有一个进程进入的区域。在C#中通过语句lock来声明临界区。lock声明后面的代码,不管是以行还是一块代码,在同一时间最多只能有一个进程执行。

9.线程的优先级具有不可靠性,就是说不能用优先级来控制线程的执行顺序。

10.后台线程

  • ①.什么是后台线程?比起应用程序的主图形用户界面(GUI)线程来说,这些线程以较低的优先权在不同的过程中运行着。对于不能立即执行结束, 又不想一直等待的任务,后台线程能很好的胜任。在C#中,把线程对象的  IsBackground属性设为true,该线程即为后台线程。    后台线程跟前台线程只有一个区别,那就是后台线程不妨碍程序的终止。一旦一个进程所有的前台线程都终止后,CLR将通过调用任意一个存活中的后台进程的Abort()方法来彻底终止进程。注意:后台线程不能直接操作所在进程之外的数据引用。
  • ②.怎样与后台线程通讯?运用MethodInvoker委派实体。也可在初始化(构造函数)中加入下面一句即可实现通讯:

Control.CheckForIllegalCrossThreadCalls = False;

要使用MethodInvoker委派,需要三个条件:

  •   a.一个创建委派的后台线程
Thread thread=new Thread(new ThreadStart(Run));

thread.IsBackground=true;  //把Thread设为后台线程

thread.Start();
  •   b.一个用作后台线程与前台可视化单元的接口的类级方法
 public void Run()
        {
            int count = 0;
            try
            {
                MethodInvoker mi = new MethodInvoker(this.UpdateLabel);
                //创建一个委托,UpdateLabel是该委托所托管的代码,必须是声明为void 且不接受任何参数的任何方法。
                while (true)
                {
                    count++;
                    //this.Invoke(mi);//同步执行委托
                    this.BeginInvoke(mi);//异步执行委托
                    Thread.Sleep(500);
                }
            }
            catch (ThreadInterruptedException e)
            {
                Console.WriteLine("Interruption Exception in Thread:{0}", e);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception in Thread:{0}", ex);
            }
        }
  •   c.一个应用程序中可以更新的可视化单元
public void UpdateLabel()
{     
    label1.Text=count.ToString();   
}

.NET Windows Forms C# 线程中的全局异常处理

异常处理

任何线程创建范围内try/catch/finally块,当线程开始执行便不再与其有任何关系。考虑下面的程序:

public static void Main() {
try {
       new Thread (Go).Start();
}
catch (Exception ex) {
       // 不会在这得到异常
       Console.WriteLine ("Exception!");
}

static void Go() { throw null; }
}

这里try/catch语句一点用也没有,新创建的线程将引发NullReferenceException异常。当你考虑到每个线程有独立的执行路径的时候,便知道这行为是有道理的,补救方法是在线程处理的方法内加入他们自己的异常处理:

public static void Main() {
      new Thread (Go).Start();
}

static void Go() {
try {
       ...
       throw null;         // 这个异常在下面会被捕捉到
       ...
}
catch (Exception ex) {
       记录异常日志,并且或通知另一个线程
       我们发生错误
       ...
}

从.NET 2.0开始,任何线程内的未处理的异常都将导致整个程序关闭,这意味着忽略异常不再是一个选项了。因此为了避免由未处理异常引起的程序崩溃,try/catch块需要出现在每个线程进入的方法内,至少要在产品程序中应该如此。对于经常使用“全局”异常处理的Windows Forms程序员来说,这可能有点麻烦,像下面这样:

using System;
using System.Threading;
using System.Windows.Forms;

static class Program {
static void Main() {
       Application.ThreadException += HandleError;
       Application.Run (new MainForm());
}

static void HandleError (object sender, ThreadExceptionEventArgs e) {
       记录异常或者退出程序或者继续运行...
}
}

Application.ThreadException事件在异常被抛出时触发,以一个Windows信息(比如:键盘,鼠标活着 “paint” 等信息)的方式,简言之,一个Windows Forms程序的几乎所有代码。虽然这看起来很完美,它使人产生一种虚假的安全感——所有的异常都被中央异常处理捕捉到了。由工作线程抛出的异常便是一个没有被Application.ThreadException捕捉到的很好的例外。(在Main方法中的代码,包括构造器的形式,在Windows信息开始前先执行)

.NET framework为全局异常处理提供了一个更低级别的事件:AppDomain.UnhandledException,这个事件在任何类型的程序(有或没有用户界面)的任何线程有任何未处理的异常触发。尽管它提供了好的不得已的异常处理解决机制,但是这不意味着这能保证程序不崩溃,也不意味着能取消.NET异常对话框。

c# 获取HTTP headers 以及获取页面title

在写一个工具, 其中一个功能是检测收集服务器的一些信息, 需要在一个操作中取到HTTP headers 信息和 页面的标题(title).

尝试了WebRequest,WebResponse和 HttpWebRequest,HttpWebResponse. 研究他们的不同, 有Http的提供 了对无Http类的 HTTP 特定方法的实现. 关键似乎找不到我的要求”在一次操作中”完成获取到HTTP headers 和 title.

最后突然看到了一段国外代码中用到WebClient, 虽然功能不尽相同, 但又多了一点思路.  进行一翻测试, 发现WebClient十分简便好用, 代码量也骤减. 虽然效率可能会略慢一些,但是做到了一次调用, 取到headers 和 title.

代码如下:

//方法函数		
		/// <summary>
		/// 返回 HTTP headers.
		/// </summary>
		/// <param name="Url">地址</param>
		/// <returns>headers的列表</returns>
		public Dictionary<string, string> GetHTTPResponseHeaders(string url)
		{
		    Dictionary<string, string> HeaderList = new Dictionary<string, string>();

            WebClient x = new WebClient();
            x.Headers.Set("Timeout", "6000"); //超时设置6秒
            string source = x.DownloadString(url);

            //用正则表达式取页面标题
            string title = Regex.Match(source, @"<titleb[^>]*>s*(?<Title>[sS]*?)</title>", RegexOptions.IgnoreCase).Groups["Title"].Value;
            HeaderList.Add("Address", url); //加入地址
            HeaderList.Add("Title", title); //加入页面标题

            foreach (string HeaderKey in x.ResponseHeaders)
                HeaderList.Add(HeaderKey, x.ResponseHeaders[HeaderKey]);

		    return HeaderList;
		}

//调用
		void Button2Click(object sender, EventArgs e)
		{
			Dictionary<string, string> Headers = GetHTTPResponseHeaders("http://www.bohu.cn/");

			foreach (string HeaderKey in Headers.Keys) 
			    textBox5.Text += HeaderKey+" : "+Headers[HeaderKey]+"rn";
		}

.Net Framework 中相关技术简介

Windows Workflow Foundation(WF):工作流引擎,基于工作流的开发使程序的业务逻辑与代码相分离,从而可以大大提高软件开发的效率。

Windows Communication Foundation(WCF): 用于实现应用程序间(包含不同语言开发的程序)通信的技术,WCF构建在SOAP协议之上。

Windows Presentation Foundation(WPF): 集成WebForm与WinForm于一体的界面开发方案

WPF的全称是Windows Presentation Foundation,是微软新发布的Vista操作系统的三大核心开发库之一,其主要负责的是图形显示,所以叫Presentation(呈现)。
作为新的图形引擎,WPF是基于DirectX的,当然增加了很多新的功能。其2D和3D引擎的强大看看Vista的界面就明白了,再加上其对Aero图形引擎的支持,更加让你刚到神奇。顺便提一下,Aero是专门为3D桌面开发的引擎,可以让桌面实现神奇的3D翻转,这绝对是操作系统有史以来的一次神奇尝试,虽然对硬件配置的要求也是惊人的,此前已有相关报道称,Vista对显卡十分挑剔就是出于运行Aero的考虑。

P.S. : WPF就是所谓下一代Windows界面层技术,就算是winform的下一代吧。

Windows通信基础(Windows Communication Foundation,WCF)是基于Windows平台下开发和部署服务的软件开发包(Software Development Kit,SDK)。WCF为服务提供了运行时环境(Runtime Environment),使得开发者能够将CLR类型公开为服务,又能够以CLR类型的方式使用服务。理论上讲,创建服务并不一定需要WCF,但实际上,使用WCF却可以使得创建服务的任务事半功倍。WCF是微软对一系列产业标准定义的实现,包括服务交互、类型转换、封送(Marshaling)以及各种协议的管理。

P.S. : 它整合了.Net平台下所有的和分布式系统有关的技术,例如ASP.NET Web服务(ASMX)、增强Web服务扩展(WSE)、.Net Remoting、企业服务(Enterprise Service)和微软消息队列(MSMQ)。你就先把它想成Web Service的下一代也没什么问题。

LINQ,语言集成查询(Language INtegrated Query)是一组用于c#和Visual Basic语言的扩展。它允许编写C#或者Visual Basic代码以查询数据库相同的方式操作内存数据。

继续阅读“.Net Framework 中相关技术简介”

Excel 数字列名(序号)与字母列名(序号)的转换

2012年2月6日作者:enet

 

来自: http://www.tal-rasha.com/archives/254.html
写代码使用到的Excel索引间的转换,其实就是十进制和二十六进制间的转换

        /// <summary>
        /// 用于excel表格中字母转成索引,从1对应A开始
        /// </summary>
        /// <param name="column">号</param>
        /// <returns>索引</returns>
        private int ColumnToIndex(string column)
        {
            if (!Regex.IsMatch(column.ToUpper(), @"[A-Z]+"))
            {
                throw new Exception("Invalid parameter");
            }
            int index = 0;
            char[] chars = column.ToUpper().ToCharArray();
            for (int i = 0; i < chars.Length; i++)
            {
                index += ((int)chars[i] - (int)'A' + 1) * (int)Math.Pow(26, chars.Length - i - 1);
            }
            return index;
        }

        /// <summary>
        /// 用于将excel表格中索引转成字母,从A对应1开始
        /// </summary>
        /// <param name="index">索引</param>
        /// <returns>号</returns>
        private string IndexToColumn(int index)
        {
            if (index <= 0)
            {
                throw new Exception("Invalid parameter");
            }
            index--;
            string column = string.Empty;
            do
            {
                if (column.Length > 0)
                { index--;
                }
                column = ((char)(index % 26 + (int)'A')).ToString() + column;
                index = (int)((index - index % 26) / 26);
            } while (index > 0);
            return column;
        }

Visual C# .NET 2003 语言的改变

摘要:为了与欧洲计算机制造商协会 (ECMA) 的 C# 规范完全兼容,Microsoft Corporation 对 C# 编译器的实现进行了几处改动。这些改动将在多方面影响现有的代码,因此用户必须检查他们的代码以确保这些代码符合 C# 编程语言必需的和推荐的使用要求。 目录 背景
C# 语言的新功能
实现的改变
小结
背景

2001 年年底,ECMA 将 C# 编程语言批准为一项标准 (ECMA-334)。为了与 Microsoft 在 C# 和公共语言接口 (CLI) 标准化进程方面的举措保持一致,Microsoft 遵循 ECMA C# 标准的精神和文字规范对 C# 编译器进行了几处小的改动。另外,Microsoft 在遵循 C# 标准规范的同时对 C# 实现作了一些额外的小改动,并更正了 C# 程序员遇到的一些编译器问题和错误。其中的每处改动都可能导致使用 Visual C# .NET 2002 版编译器编写的代码在用于 Visual C# .NET 2003 之前必须进行修改。
C# 语言的新功能 Visual C# .NET 2003 版的 C# 语言中添加了两个新功能。第一,编译器现在支持 #line hidden 预处理器指令。#line hidden 指令主要用于源代码生成器,它通知编译器忽略紧跟在 #line hidden 指令后面的所有代码行的调试程序信息,直到遇到下一个 #line 指令为止(该 #line 指令的调试程序信息也一并被忽略),这里假设它们中间不会立即碰到下一个 #line hidden 预处理指令。在下面的示例中,编译器生成了 IL 代码,其中的 WriteLine 语句不包含调试信息。这样,调试应用程序的程序员将无法查看“隐藏”的代码并检查其中的内容:

public class Customer
{

简单的加减乘除实例 C#

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace WinForm_p169_2
{
        /// <summary>
        /// Form2 的摘要说明。
        /// </summary>
        public class Form2 : System.Windows.Forms.Form
        {
                private System.Windows.Forms.ToolBar toolBar1;
                private System.Windows.Forms.ToolBarButton toolBarButton1;
                private System.Windows.Forms.ToolBarButton toolBarButton2;
                private System.Windows.Forms.ToolBarButton toolBarButton3;
                private System.Windows.Forms.ToolBarButton toolBarButton4;
                private System.Windows.Forms.Label label1;
                private System.Windows.Forms.Label label2;
                private System.Windows.Forms.TextBox textBox1;
                private System.Windows.Forms.TextBox textBox2;
                private System.Windows.Forms.StatusBar statusBar1;
                private System.Windows.Forms.StatusBarPanel statusBarPanel1;
                private System.Windows.Forms.StatusBarPanel statusBarPanel2;
                int a,b,x; // 运算所需的3个变量
                /// <summary>
                /// 必需的设计器变量。
                /// </summary>
                private System.ComponentModel.Container components = null;

                public Form2()
                {
                        //
                        // Windows 窗体设计器支持所必需的
                        //
                        InitializeComponent();

                        //
                        // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
                        //
                }

                /// <summary>
                /// 清理所有正在使用的资源。
                /// </summary>
                protected override void Dispose( bool disposing )
                {
                        if( disposing )
                        {
                                if(components != null)
                                {
                                        components.Dispose();
                                }
                        }
                        base.Dispose( disposing );
                }

                #region Windows 窗体设计器生成的代码
                /// <summary>
                /// 设计器支持所需的方法 - 不要使用代码编辑器修改
                /// 此方法的内容。
                /// </summary>
                private void InitializeComponent()
                {
                        this.toolBar1 = new System.Windows.Forms.ToolBar();
                        this.toolBarButton1 = new System.Windows.Forms.ToolBarButton();
                        this.toolBarButton2 = new System.Windows.Forms.ToolBarButton();
                        this.toolBarButton3 = new System.Windows.Forms.ToolBarButton();
                        this.toolBarButton4 = new System.Windows.Forms.ToolBarButton();
                        this.label1 = new System.Windows.Forms.Label();
                        this.label2 = new System.Windows.Forms.Label();
                        this.textBox1 = new System.Windows.Forms.TextBox();
                        this.textBox2 = new System.Windows.Forms.TextBox();
                        this.statusBar1 = new System.Windows.Forms.StatusBar();
                        this.statusBarPanel1 = new System.Windows.Forms.StatusBarPanel();
                        this.statusBarPanel2 = new System.Windows.Forms.StatusBarPanel();
                        ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).BeginInit();
                        ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel2)).BeginInit();
                        this.SuspendLayout();
                        //
                        // toolBar1
                        //
                        this.toolBar1.Buttons.AddRange(new System.Windows.Forms.ToolBarButton[] {
                                                                                                                                                                                this.toolBarButton1,
                                                                                                                                                                                this.toolBarButton2,
                                                                                                                                                                                this.toolBarButton3,
                                                                                                                                                                                this.toolBarButton4});
                        this.toolBar1.DropDownArrows = true;
                        this.toolBar1.Location = new System.Drawing.Point(0, 0);
                        this.toolBar1.Name = "toolBar1";
                        this.toolBar1.ShowToolTips = true;
                        this.toolBar1.Size = new System.Drawing.Size(292, 41);
                        this.toolBar1.TabIndex = 0;
                        this.toolBar1.ButtonClick += new System.Windows.Forms.ToolBarButtonClickEventHandler(this.toolBar1_ButtonClick);
                        //
                        // toolBarButton1
                        //
                        this.toolBarButton1.Tag = "+";
                        this.toolBarButton1.Text = "加";
                        //
                        // toolBarButton2
                        //
                        this.toolBarButton2.Tag = "-";
                        this.toolBarButton2.Text = "减";
                        //
                        // toolBarButton3
                        //
                        this.toolBarButton3.Tag = "*";
                        this.toolBarButton3.Text = "乘";
                        //
                        // toolBarButton4
                        //
                        this.toolBarButton4.Tag = "/";
                        this.toolBarButton4.Text = "除";
                        //
                        // label1
                        //
                        this.label1.Location = new System.Drawing.Point(27, 79);
                        this.label1.Name = "label1";
                        this.label1.Size = new System.Drawing.Size(63, 27);
                        this.label1.TabIndex = 1;
                        this.label1.Text = "第一个数";
                        //
                        // label2
                        //
                        this.label2.Location = new System.Drawing.Point(25, 133);
                        this.label2.Name = "label2";
                        this.label2.Size = new System.Drawing.Size(63, 27);
                        this.label2.TabIndex = 2;
                        this.label2.Text = "第二个数";
                        //
                        // textBox1
                        //
                        this.textBox1.Location = new System.Drawing.Point(94, 77);
                        this.textBox1.Name = "textBox1";
                        this.textBox1.Size = new System.Drawing.Size(129, 21);
                        this.textBox1.TabIndex = 3;
                        this.textBox1.Text = "0";
                        //
                        // textBox2
                        //
                        this.textBox2.Location = new System.Drawing.Point(92, 130);
                        this.textBox2.Name = "textBox2";
                        this.textBox2.Size = new System.Drawing.Size(129, 21);
                        this.textBox2.TabIndex = 4;
                        this.textBox2.Text = "0";
                        //
                        // statusBar1
                        //
                        this.statusBar1.Location = new System.Drawing.Point(0, 251);
                        this.statusBar1.Name = "statusBar1";
                        this.statusBar1.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
                                                                                                                                                                                  this.statusBarPanel1,
                                                                                                                                                                                  this.statusBarPanel2});
                        this.statusBar1.ShowPanels = true;
                        this.statusBar1.Size = new System.Drawing.Size(292, 22);
                        this.statusBar1.TabIndex = 5;
                        this.statusBar1.Text = "statusBar1";
                        //
                        // statusBarPanel1
                        //
                        this.statusBarPanel1.Text = "结果";
                        //
                        // Form2
                        //
                        this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
                        this.ClientSize = new System.Drawing.Size(292, 273);
                        this.Controls.Add(this.statusBar1);
                        this.Controls.Add(this.textBox2);
                        this.Controls.Add(this.textBox1);
                        this.Controls.Add(this.label2);
                        this.Controls.Add(this.label1);
                        this.Controls.Add(this.toolBar1);
                        this.Name = "Form2";
                        this.Text = "Form2";
                        ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).EndInit();
                        ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel2)).EndInit();
                        this.ResumeLayout(false);

                }
                #endregion
                // 函数验证是否为数字
                public bool IsNumeric(string str)
                {
                        try
                        {
                                // 先判断是否为整形
                                Int32.Parse(str);
                        }
                        catch
                        {
                                // 在判断是否为浮点型
                                try
                                {
                                        Double.Parse(str);
                                }
                                catch
                                {
                                        return false;
                                }
                        }
                        return true;
                }

                // 运算函数
                public void NumOperation(string o)
                {
                        // 判断输入是否为空
                        if((textBox1.Text!=null)||(textBox2.Text!=null))
                        {
                                // 判断是否为数字
                                if(!IsNumeric(textBox1.Text)||!IsNumeric(textBox2.Text))
                                {
                                        this.textBox1.Text="0";
                                        this.textBox2.Text="0";
                                }
                                else
                                {
                                        // 转换输入的2个字符串为数字
                                        a=System.Convert.ToInt32(this.textBox1.Text);
                                        b=System.Convert.ToInt32(this.textBox2.Text);
                                        if(o=="+")
                                                x=a+b;
                                        if(o=="-")
                                                x=a-b;
                                        if(o=="*")
                                                x=a*b;
                                        if(o=="/")
                                                if(b==0)
                                                {
                                                        MessageBox.Show("除数不能为0!");
                                                        this.textBox2.SelectAll();
                                                }
                                                else
                                                        x=a/b;
                                        // 显示结果
                                        statusBarPanel2.Text=x.ToString();
                                }
                        }
                }

                private void toolBar1_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)
                {
                        // 调用按钮
                        this.NumOperation(e.Button.Tag.ToString());
                }
        }
}

 

Visual C# .NET 2003

ÕªÒª£ºÎªÁËÓëÅ·ÖÞ¼ÆËã»úÖÆÔìÉÌЭ»á (ECMA) µÄ C# ¹æ·¶ÍêÈ«¼æÈÝ£¬Microsoft Corporation ¶Ô C# ±àÒëÆ÷µÄʵÏÖ½øÐÐÁ˼¸´¦¸Ä¶¯¡£ÕâЩ¸Ä¶¯½«ÔÚ¶à·½ÃæÓ°ÏìÏÖÓеĴúÂ룬Òò´ËÓû§±ØÐë¼ì²éËûÃǵĴúÂëÒÔÈ·±£ÕâЩ´úÂë·ûºÏ C# ±à³ÌÓïÑÔ±ØÐèµÄºÍÍÆ¼öµÄʹÓÃÒªÇó¡£
Ŀ¼
±³¾°
C# ÓïÑÔµÄй¦ÄÜ
ʵÏֵĸıä
С½á

±³¾°

2001 ÄêÄêµ×£¬ECMA ½« C# ±à³ÌÓïÑÔÅú׼ΪһÏî±ê×¼ (ECMA-334)¡£ÎªÁËÓë Microsoft ÔÚ C# ºÍ¹«¹²ÓïÑÔ½Ó¿Ú (CLI) ±ê×¼»¯½ø³Ì·½ÃæµÄ¾Ù´ë±£³ÖÒ»Ö£¬Microsoft ×ñÑ­ ECMA C# ±ê×¼µÄ¾«ÉñºÍÎÄ×ֹ淶¶Ô C# ±àÒëÆ÷½øÐÐÁ˼¸´¦Ð¡µÄ¸Ä¶¯¡£ÁíÍ⣬Microsoft ÔÚ×ñÑ­ C# ±ê×¼¹æ·¶µÄͬʱ¶Ô C# ʵÏÖ×÷ÁËһЩ¶îÍâµÄС¸Ä¶¯£¬²¢¸üÕýÁË C# ³ÌÐòÔ±Óöµ½µÄһЩ±àÒëÆ÷ÎÊÌâºÍ´íÎ󡣯äÖеÄÿ´¦¸Ä¶¯¶¼¿ÉÄܵ¼ÖÂʹÓà Visual C# .NET 2002 °æ±àÒëÆ÷±àдµÄ´úÂëÔÚÓÃÓÚ Visual C# .NET 2003 ֮ǰ±ØÐë½øÐÐÐ޸ġ£
C# ÓïÑÔµÄй¦ÄÜ
Visual C# .NET 2003 °æµÄ C# ÓïÑÔÖÐÌí¼ÓÁËÁ½¸öй¦ÄÜ¡£µÚ
Àà±ð£º³ÌÐò´úÂ렲鿴ÆÀÂÛ]]>