博文

C#多线程编程(4)-多线程与UI操作(2011-01-16 15:34:00)

摘要: 为了让程序尽快响应用户操作,在开发Windows应用程序时经常会使用到线程。对于耗时的操作如果不使用线程将会是UI界面长时间处于停滞状态,这种情况是用户非常不愿意看到的,在这种情况下我们希望使用线程来解决这个问题。
下面是一个使用多线程操作界面UI的代码: using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ThreadPoolDemo
{
public partial class ThreadForm : Form
{
public ThreadForm()
{
InitializeComponent();
}

private void btnThread_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(Run));
thread.Start();
}

private void Run()
{
while (progressBar.Value < progressBar.Maximum)
{
progres......

阅读全文(5301) | 评论:1

.Net Remoting(2011-01-15 16:42:00)

摘要:原文地址: http://www.cnblogs.com/wayfarer/archive/ Microsoft .Net Remoting系列专题之一 一、Remoting基础 什么是Remoting,简而言之,我们可以将其看作是一种分布式处理方式。从微软的产品角度来看,可以说Remoting就是DCOM的一种升级,它改善了很多功能,并极好的融合到.Net平台下。Microsoft® .NET Remoting 提供了一种允许对象通过应用程序域与另一对象进行交互的框架。这也正是我们使用Remoting的原因。为什么呢?在Windows操作系统中,是将应用程序分离为单独的进程。这个进程形成了应用程序代码和数据周围的一道边界。如果不采用进程间通信(RPC)机制,则在一个进程中执行的代码就不能访问另一进程。这是一种操作系统对应用程序的保护机制。然而在某些情况下,我们需要跨过应用程序域,与另外的应用程序域进行通信,即穿越边界。 在Remoting中是通过通道(channel)来实现两个应用程序域之间对象的通信的。如图所示: 首先,客户端通过Remoting,访问通道以获得服务端对象,再通过代理解析为客户端对象。这就提供一种可能性,即以服务的方式来发布服务器对象。远程对象代码可以运行在服务器上(如服务器激活的对象和客户端激活的对象),然后客户端再通过Remoting连接服务器,获得该服务对象并通过序列化在客户端运行。 在Remoting中,对于要传递的对象,设计者除了需要了解通道的类型和端口号之外,无需再了解数据包的格式。但必须注意的是,客户端在获取服务器端对象时,并不是获得实际的服务端对象,而是获得它的引用。这既保证了客户端和服务器端有关对象的松散耦合,同时也优化了通信的性能。 1、Remoting的两种通道 Remoting的通道主要有两种:Tcp和Http。在.Net中,System.Runtime.Remoting.Channel中定义了IChannel接口。IChannel接口包括了TcpChannel通道类型和Http通道类型。它们分别对应Remoting通道的这两种类型。 TcpChannel类型放在名字空间System.Runtime.Remoting.Channel.Tcp中。Tcp通道提供了基于Socket的传输工具,使用......

阅读全文(2154) | 评论:2

C#结构体的特点浅析(2010-11-02 10:13:00)

摘要:C#结构体的特点是什么呢?让我们来看看: C#结构体之struct 类型是一种值类型,通常用来封装小型相关变量组,例如,矩形的坐标或库存商品的特征。下面的示例显示了一个简单的结构声明。 public struct PostalAddress   {   // Fields, properties, methods and events go here...   }  结构与类共享几乎所有相同的语法,但结构比类受到的限制更多: 尽管结构的静态字段可以初始化,结构实例字段声明还是不能使用初始值设定项。 结构不能声明默认构造函数(没有参数的构造函数)或析构函数。 C#结构体之结构的副本由编译器自动创建和销毁,因此不需要使用默认构造函数和析构函数。实际上,编译器通过为所有字段赋予默认值(参见默认值表)来实现默认构造函数。结构不能从类或其他结构继承。 结构是值类型 -- 如果从结构创建一个对象并将该对象赋给某个变量,变量则包含结构的全部值。复制包含结构的变量时,将复制所有数据,对新副本所做的任何修改都不会改变旧副本的数据。由于结构不使用引用,因此结构没有标识 -- 具有相同数据的两个值类型实例是无法区分的。C# 中的所有值类型本质上都继承自 ValueType,后者继承自Object。 C#结构体之编译器可以在一个称为装箱的过程中将值类型转换为引用类型。 C#结构体之结构具有以下特点: 结构是值类型,而类是引用类型 向方法传递结构时.结构是通过传值方式传递的,不是作为引用方式传递. 与类不同,结构的实例化可以不使用new运算符. 结构可以声明构造函数,但他们必须带参数 一个结构不能从另一个结构或类继承,而且不能作为一个类的基。所有结构都直接继承自 System.ValueType,后者继承自 System.Object。 C#结构体之结构可以实现接口。 在结构中初始化实例字段是错误的。 C#结构体的相关内容就向你介绍到这里,希望对你了解C#结构体有所帮助。 ......

阅读全文(2305) | 评论:0

.Net多线程编程方法总结(第一部分)(2010-11-01 22:48:00)

摘要:.Net提供了许多多线程编程工具,可能是因为太多了,所以掌握起来总是有一些头疼,我在这里讲讲我总结的一些多线程编程的经验,希望对大家有帮助   不需要传递参数,也不需要返回参数
我们知道启动一个线程最直观的办法是使用Thread类,具体步骤如下 ThreadStart threadStart=new ThreadStart(Calculate);
Thread thread=new Thread(threadStart);
thread.Start();

public void Calculate(){
double Diameter=0.5;
Console.Write("The perimeter Of Circle with a Diameter of {0} is {1}"Diameter,Diameter*Math.PI);
}
例1 上面我们用定义了一个ThreadStart类型的委托,这个委托制定了线程需要执行的方法:Calculate,在这个方法里计算了一个直径为0.5的圆的周长,并输出.这就构成了最简单的多线程的例子,在很多情况下这就够用了,然后ThreadStart这个委托定义为void ThreadStart(),也就是说,所执行的方法不能有参数,这显然是个很大的不足,为了弥补这个缺陷,聪明的程序员想出了许多好的方法,我们将在需要传递多个参数一节中进行介绍,这里我们先介绍.Net为了解决这个问题而设定的另外一个委托:就是ParameterizedThreadStart ,我会在下面详细讲述 需要传递单个参数 ParameterThreadStart的定义为void ParameterizedThreadStart(object state)??使用这个这个委托定义的线程的启动函数可以接受一个输入参数,具体例子如下
ParameterizedThreadStart threadStart=new ParameterizedThreadStart(Calculate)
Thread thread=new Thread()
thread......

阅读全文(1773) | 评论:0

.NET多线程编程(2):System.Threading.Thread类(2010-11-01 21:59:00)

摘要:  在接下来的这篇文章中,我将向大家介绍.NET中的线程API,怎么样用C#创建线程,启动和停止线程,设置优先级和状态.   在.NET中编写的程序将被自动的分配一个线程.让我们来看看用C#编程语言创建线程并且继续学习线程的知识。我们都知道.NET的运行时环境的主线程由Main ()方法来启动应用程序,而且.NET的编译语言有自动的垃圾收集功能,这个垃圾收集发生在另外一个线程里面,所有的这些都是后台发生的,让我们无法感觉到发生了什么事情.在这里默认的是只有一个线程来完成所有的程序任务,但是正如我们在第一篇文章讨论过的一样,有可能我们根据需要自己添加更多的线程让程序更好的协调工作。比如说我们的例子中,一个有用户输入的同时需要绘制图形或者完成大量的运算的程序,我们必须得增加一个线程,让用户的输入能够得到及时的响应,因为输入对时间和响应的要求是紧迫的,而另外一个线程负责图形绘制或者大量的运算。   .NET 基础类库的System.Threading命名空间提供了大量的类和接口支持多线程。这个命名空间有很多的类,我们将在这里着重讨论Thread这个类。   System.Threading.Thread类是创建并控制线程,设置其优先级并获取其状态最为常用的类。他有很多的方法,在这里我们将就比较常用和重要的方法做一下介绍: Thread.Start():启动线程的执行; Thread.Suspend():挂起线程,或者如果线程已挂起,则不起作用; Thread.Resume():继续已挂起的线程; Thread.Interrupt():中止处于 Wait或者Sleep或者Join 线程状态的线程; Thread.Join():阻塞调用线程,直到某个线程终止时为止 Thread.Sleep():将当前线程阻塞指定的毫秒数; Thread.Abort():以开始终止此线程的过程。如果线程已经在终止,则不能通过Thread.Start()来启动线程。   通过调用Thread.Sleep,Thread.Suspend或者Thread.Join可以暂停/阻塞线程。调用Sleep()和Suspend()方法意味着线程将不再得到CPU时间。这两种暂停线程的方法是有区别的,Sleep()使得线程立即停止执行,但是在调用Suspend()......

阅读全文(2006) | 评论:0

[C#初学课堂]多线程:Thread类的Join()方法(2010-11-01 15:27:00)

摘要:  [说明:刚接触多线程时,弄不明白Join()的作用,查阅了三本书,都不明不白。后来经过自己的一番试验,终于弄清了Join()的本质。大家看看我这种写法是否易懂,是否真的写出了Join()的本质,多提宝贵意见。]   Thread类的Join()方法能够将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,线程A将插入线程B之前,直到线程A执行完毕后,才会继续执行线程B。   试一试:线程的插入   //《C#初学课堂》
    //注意添加命名空间
    using System.Threading;
  
    static void Main(string[] args)
阅读全文(2472) | 评论:0

.Net基础:readonly const 区别(2010-10-20 17:11:00)

摘要:我们都知道,const和static readonly的确很像:通过类名而不是对象名进行访问,在程序中只读等等。在多数情况下可以混用。
二者本质的区别在于,const的值是在编译期间确定的,因此只能在声明时通过常量表达式指定其值。而static readonly是在运行时计算出其值的,所以还可以通过静态构造函数来赋值。
明白了这个本质区别,我们就不难看出下面的语句中static readonly和const能否互换了:
1. static readonly MyClass myins = new MyClass();
2. static readonly MyClass myins = null;
3. static readonly A = B * 20;
   static readonly B = 10;
4. static readonly int [] constIntArray = new int[] {1, 2, 3};
5. void SomeFunction()
   {
      const int a = 10;
      ...
   } 1:不可以换成const。new操作符是需要执行构造函数的,所以无法在编译期间确定
2:可以换成const。我们也看到,Reference类型的常量(除了String)只能是Null。
3:可以换成const。我们可以在编译期间很明确的说,A等于200。
4:不可以换成const。道理和1是一样的,虽然看起来1,2,3的数组的确就是一个常量。
5:不可以换成readonly,readonly只能用来修饰类的field,不能修饰局部变量,也不能修饰property等其他类成员 C#引入了readonly修饰符来表示只读域,const来表示不变常量。顾名思义对只读域不能进行写操作,不变常量不能被修改,这两者到底有什 么区别......

阅读全文(2379) | 评论:0

ADO.net操作数据库总结(2010-10-20 14:27:00)

摘要:一.用SqlConnection连接SQL Server 
1..加入命名空间 
using System.Data.SqlClient; 2.连接数据库 
SqlConnection myConnection = new SqlConnection(); 
myConnection.ConnectionString = "user id=sa;password=sinofindb;initial catalog=test;data source=127.0.0.1;Connect Timeout=30"; 
myConnection.Open(); 改进(更通用)的方法: 
string MySqlConnection="user id=sa;password=sinofindb;Database =test;data source=127.0.0.1;Connect Timeout=30"; 
SqlConnection myConnection = new SqlConnection(MySqlConnection); 
myConnection.Open(); 二.创建Command对象 1.SqlCommand 构造函数 ①初始化 SqlCommand 类的新实例。
  public SqlCommand(); 
  SqlCommand myCommand = new SqlCommand(); ②初始化具有查询文本的 SqlCommand 类的新实例。public SqlCommand(string); 
  String mySelectQuery = "Select * FROM mindata"; 
  SqlCommand myCommand = new SqlCommand(mySelectQuery); ③初始化具有查询文本和 SqlConnection 的SqlCommand类实例。 
&......

阅读全文(1683) | 评论:0

如何测试私有/受保护的方法? (译文) (二)(2010-07-21 10:35:00)

摘要:4.   测试私有方法 测试私有方法稍微复杂些,但我们可以利用System.Reflection。你可以利用反射动态的访问一个类型的方法,包括实例和静态的私有方法。要注意的是访问私有方法需要ReflectionPermission,但在开发机或BUILD机上运行单元测试不是问题。 假设我们要测试ClassLibrary1.MyObject类的MyPrivateMethod私有方法: private string MyPrivateMethod(string strInput, DateTime dt, double  dbl) {     return this.Name + ": " + strInput + ", " +      dt.ToString() + ", " + dbl.ToString(); } 一种解决方法是建立一个UnitTestUtilities 工程包含一个UnitTestUtilities.Helper类,用于通过反射调用测试方法。 public static object RunStaticMethod(System.Type t, string strMethod,  object [] aobjParams) {     BindingFlags eFlags =      BindingFlags.Static | BindingFlags.Public |      BindingFlags.NonPublic;     return RunMethod(t, strMethod,      null, aobjParams, eFlags); } //end of method public static object RunInstanceMethod(System.Type t, string strMethod,  object objInstan......

阅读全文(2070) | 评论:0

如何测试私有/受保护的方法? (译文) (一)(2010-07-21 10:31:00)

摘要:       1.   简介     Test Driven Development 的步骤是先写测试,然后写代码让测试通过,然后再重构。这些概念在.net环境中由于对软件质量要求的提高,越来越受到重视。测试公有方法是很容易的,自然而然的就有问题产生了“如何测试protected或private方法”?本文包括: l         总结一些测试私有方法的常用做法; l         给出一些有用的方法,即使你不知道哪种方法最优; l         提高代码演示这些测试技术。   2.   背景 2.1. 是否应该测试私有方法? 在GOOGLE(Google search)上搜索一下就会发现无数相关讨论,更不用说实际的测试实现了。下面的表格对这些讨论做了总结,并把利弊都列出如下:   观点 利 弊 使用私有方法 封装- 私有函数提供了封装,方便了客户端的调用。 重构- 重构私有方法很容易,因为没有被外部调用,因此修改其声明方式不会破坏外面的任何调用。 校验- 不象公有方法必须要校验外部的输入数据,私有方法不需要复杂的校验(因为在公有方法中已经校验过)。 测试范围- 将所有方法设成公有,扩大了测试的范围。私有方法只有在开发人员需要时才测试,公有方法使用广泛,必须要全部测试。 不重构- 如果一个类复杂到不需要使用私有方法,则应该进行重构。 功能隐藏- 私有方法(如果设计正确的话)提供了有用的特性,如果需要客户端访问而测试的话,则应该设置为公有。 测试私有方法 测试控制- 私有方法可能包含了复杂的逻辑,测试应该包含这些方法的测试,而不能因为公有方法中调用了这些方法就认为没有问题。 原则- 单元测试用......

阅读全文(2685) | 评论:0