Just Focus on Techonology

Lead My Life

置顶随笔 #

[置顶]原来线程-2 (直面多线程)

posted @ 2006-07-07 05:06 ColinYang 阅读(1823) 评论(7) 编辑

2006年9月25日 #

Direct 10 News

        微软Vista团队博客上公布了DirectX 10的精彩的游戏画面,同时与DirectX 9进行了对比,更加突出了DirectX 10形象逼真的3D效果,大家快来欣赏一下吧。

        DirectX 10是DirectX的一个新版本,通过重建改进了CPU和GPU之间的材质管理和负载平衡,改进了二者之间的通讯联系。

        微软曾表示,DirectX 10只为Windows Vista平台发布,将与Windows Vista一同发布。DirectX 10需要WDDM驱动支持,而且加入了全新的IHV控制内核和用户模式驱动程序,而Windows XP无法支持这些功能。

        这些截图展示了DirectX 10在游戏人物、动物和Windows Vista壁纸方面与DirectX 9进行了对比,另外展示了DirectX 10在阴影体积、动态场景、运动模糊方面的逼真效果。

     一、游戏人物


DirectX 9


DirectX 9


DirectX 10

二、动物


DirectX 9


DirectX 10

三、阴影体积


DirectX 10

五、动态场景

六、运动模糊


posted @ 2006-09-25 11:23 ColinYang 阅读(371) 评论(0) 编辑

2006年7月14日 #

最近几天在做项目,好忙啊

好久没写博客了,最近几天在做项目,好忙啊.这段时间一过,就要接着写我还没有写完的<<原来线程>>系列了,看了那么多的评论,感觉写的东西是对大家那么的有用,这更坚定了我写下去的信心.相信不会让大家失望的.

posted @ 2006-07-14 23:20 ColinYang 阅读(50) 评论(0) 编辑

2006年7月7日 #

原来线程-2 (直面多线程)

posted @ 2006-07-07 05:06 ColinYang 阅读(1823) 评论(7) 编辑

2006年7月5日 #

c#v2.0 扩展特性 翻译(1)

c#v2.0 扩展特性 翻译(1)
Introduction to C# 2.0
C# 2.0 introduces several language extensions, the most important of which are Generics, Anonymous Methods, Iterators, and Partial Types.

C#2.0 介绍几种语言扩展,泛型,匿名方法,迭代器 和、partial Types.

· Generics permit classes, structs, interfaces, delegates, and methods to be parameterized by the types of data they store and manipulate. Generics are useful because they provide stronger compile-time type checking, require fewer explicit conversions between data types, and reduce the need for boxing operations and run-time type checks.

泛型允许类,结构,接口,代理还有方法被他们存储和操作数据类型参数化。泛型相当有用,因为他们提供强制的编译时类型检查,要求更少的数据类型之间的显式转换,并减少装箱拆箱的操作和运行时类型检查。

· Anonymous methods allow code blocks to be written “in-line” where delegate values are expected. Anonymous methods are similar to lambda functions in the Lisp programming language. C# 2.0 supports the creation of “closures” where anonymous methods access surrounding local variables and parameters.

· Iterators are methods that incrementally compute and yield a sequence of values. Iterators make it easy for a type to specify how the foreach statement will iterate over its elements.

· Partial types allow classes, structs, and interfaces to be broken into multiple pieces stored in different source files for easier development and maintenance. Additionally, partial types allow separation of machine-generated and user-written parts of types so that it is easier to augment code generated by a tool.

This chapter gives an introduction to these new features. Following the introduction are four chapters that provide a complete technical specification of the features.

这个章节将介绍这些新特性。随后的四个章节的介绍将提供有关特性的完整技术规范

The language extensions in C# 2.0 were designed to ensure maximum compatibility with existing code. For example, even though C# 2.0 gives special meaning to the words where, yield, and partial in certain contexts, these words can still be used as identifiers. Indeed, C# 2.0 adds no new keywords as such keywords could conflict with identifiers in existing code.

c#2.0中的语言扩展最大程度上保证和现有代码的兼容。举例说,即使c#2.0指定以下词如yield,partial在特定的上下文有特有的意义,他们依然可以作为标示符。甚至,c#2.0没有加任何新的可能会在现有代码冲突的关键词

Generics
Generics permit classes, structs, interfaces, delegates, and methods to be parameterized by the types of data they store and manipulate. C# generics will be immediately familiar to users of generics in Eiffel or Ada, or to users of C++ templates, though they do not suffer many of the complications of the latter.

泛型允许类,结构,接口,代理和方法被他们存储操作的数据类型参数化。C#泛型将很快被eiffel,ada的使用过泛型的用户熟悉,或是使用过c++templates,尽管他们不需要忍受以后的多种编译器。



Why generics?
Without generics, general purpose data structures can use type object to store data of any type. For example, the following simple Stack class stores its data in an object array, and its two methods, Push and Pop, use object to accept and return data, respectively:

如果没有泛型,一般数据结构能使用类型对象去存储任何数据类型。举例,下面所描述的一个很简单的栈的类存储数据在对象数组中。它有两个方法push和pop,使用对象分别地去接受和返回数据

public class Stack
{
object[] items;
int count;

public void Push(object item) {...}

public object Pop() {...}
}

While the use of type object makes the Stack class very flexible, it is not without drawbacks. For example, it is possible to push a value of any type, such a Customer instance, onto a stack. However, when a value is retrieved, the result of the Pop method must explicitly be cast back to the appropriate type, which is tedious to write and carries a performance penalty for run-time type checking:

当使用对象类型的时候栈类的使用更灵活,它并非没有缺陷。举例说,它很可能压入任何类型的值,如一个customer实例到一个栈。然而,当一个值返回,pop方法返回的结果必须显式转化成适当类型,不但编写是乏味的并且在运行时的类型检查降低性能。

Stack stack = new Stack();
stack.Push(new Customer());
Customer c = (Customer)stack.Pop();

If a value of a value type, such as an int, is passed to the Push method, it is automatically boxed. When the int is later retrieved, it must be unboxed with an explicit type cast:

如果是一个值类型,如整型传入push方法,它自动装箱。当整型在后来返回的时候,它必须进行显式的拆箱。

Stack stack = new Stack();
stack.Push(3);
int i = (int)stack.Pop();

Such boxing and unboxing operations add performance overhead since they involve dynamic memory allocations and run-time type checks.

当他们处于动态内存分配和运行时类型检查,装箱拆箱操作将增加性能消耗。

A further issue with the Stack class is that it is not possible to enforce the kind of data placed on a stack. Indeed, a Customer instance can be pushed on a stack and then accidentally cast it to the wrong type after it is retrieved:

进一步的关于栈的讨论,强迫数据的类别压入到栈是不可能的。事实上,一个customer实例能被压入栈并且很有可能偶然在它返回时被转化成错误的类型。



Stack stack = new Stack();
stack.Push(new Customer());
string s = (string)stack.Pop();

While the code above is an improper use of the Stack class, the code is technically speaking correct and a compile-time error is not reported. The problem does not become apparent until the code is executed, at which point an InvalidCastException is thrown.

The Stack class would clearly benefit from the ability to specify its element type. With generics, that becomes possible.

以上代码从技术上说是正确的且在编译时是不会报错的,但对stack类的用法是不正确的。这个问题直到代码执行才会显示出来,并抛出InvalidCastException异常.

栈类应当受益于指定元素类型的能力。有了泛型以后,这个将成为可能。

Creating and using generics

创建和使用泛型

Generics provide a facility for creating types that have type parameters. The example below declares a generic Stack class with a type parameter T. The type parameter is specified in < and > delimiters after the class name. Rather than forcing conversions to and from object, instances of Stack accept the type for which they are created and store data of that type without conversion. The type parameter T acts as a placeholder until an actual type is specified at use. Note that T is used as the element type for the internal items array, the type for the parameter to the Push method, and the return type for the Pop method:

泛型提供了一个便利的方法,通过类型参数去创建类型。下面的例子通过类型参数T声明了一个泛型的栈。类型参数在类名后面<>分隔符中定义。Stack实例接受它创建和存储的数据类型而不需要转换远胜于强制的对象转换。

public class Stack
{
T[] items;
int count;

public void Push(T item) {...}

public T Pop() {...}
}

When the generic class Stack is used, the actual type to substitute for T is specified. In the following example, int is given as the type argument for T:

当泛型类Stack被使用,替代T的真实类型将被指定。下面的例子里,int 被指定代替T。

Stack stack = new Stack();
stack.Push(3);
int x = stack.Pop();

The Stack type is called a constructed type. In the Stack type, every occurrence of T is replaced with the type argument int. When an instance of Stack is created, the native storage of the items array is an int[] rather than object[], providing substantial storage efficiency compared to the non-generic Stack. Likewise, the Push and Pop methods of a Stack operate on int values, making it a compile-time error to push values of other types onto the stack, and eliminating the need to explicitly cast values back to their original type when they’re retrieved.

Stack类型被称作构造类型. 在Stack里,每次出现T将被类型参数int代替。当一个Stack实例被创建,本身存储items数组是一个int型数组,比非泛型栈的对象数组提供真实性存储效率。同样的,Push和Pop方法操作int 值,如果push其他类型的数据给栈,将导致一个编译时错误,它排除了当值被返回时所要求的显式转化成原型。



Generics provide strong typing, meaning for example that it is an error to push an int onto a stack of Customer objects. Just as a Stack is restricted to operate only on int values, so is Stack restricted to Customer objects, and the compiler will report errors on the last two lines of the following example:

泛型提供强类型,意味着举例说来 将一个整型数据压入Customer 泛类型的栈。正像一个int泛型栈被严格约束只能操作int型,因此Customer型被严格要求操作Customer对象。下面例子的最后两行,编译器编译的时候会报告错误。

Stack stack = new Stack();
stack.Push(new Customer());
Customer c = stack.Pop();
stack.Push(3); // Type mismatch error
int x = stack.Pop(); // Type mismatch error

Generic type declarations may have any number of type parameters. The Stack example above has only one type parameter, but a generic Dictionary class might have two type parameters, one for the type of the keys and one for the type of the values:

泛型声明可以包括任何数目的类型参数。上面Stack的例子仅仅只有一个类型参数,但泛型Dictionary类可以含有两个类型参数,一个是关键字的类型,一个是值的类型。

public class Dictionary
{
public void Add(K key, V value) {...}

public V this[K key] {...}
}

When Dictionary is used, two type arguments would have to be supplied:

当Dictionary被使用,必须提供两种类型参数

Dictionary dict = new Dictionary();
dict.Add("Peter", new Customer());
Customer c = dict["Peter"];

posted @ 2006-07-05 23:35 ColinYang 阅读(174) 评论(2) 编辑

2006年7月3日 #

原来线程-1

 

        作为C#中较为高级的概念,线程的使用常常给开发人员,尤其是初级程序员带来不少的困惑。下面就来谈谈一些关于在Winform中使用线程的话题,在正式开始之前,我认为很有必要弄清楚一些基本概念和一些区别。

 

        什么是线程?

        也许一来就搬出一堆概念来,会让人反感,那么就从线程和进程的关系说起吧。

        在早期的多任务操作系统中,并没有独立的线程概念,只有进程概念。为了使多个任务互不干扰的运行,没个进程都拥有独立的虚拟地址空间、代码段、数据段及堆栈等,除此之外,进程还占有了各种系统资源(例如文件、窗体对象、环境变量等等)。开始执行一个程序即创建了一个进程,进程拥有自身独立的资源,进程之间相互隔离、互不干扰。而后线程出现了。多个线程作为独立的执行单元可以存在于同一个进程中。线程共享其所属进程拥有的资源,可以访问进程的内存区域和代码段,而且线程还拥有各自的局部变量和对立的栈空间。

        线程出现后,进程就作为程序运行所需公共资源的管理单元,而线程则作为程序的可执行单元,成为了任务调度的基本单元。

        上一段的斜线部分,便可作为线程的基本概念来理解,不过我简单归纳一下,线程其实就是程序中单一的顺序控制流程

 

        进程与线程的区别

       通常一个程序需要同时执行多个不同的任务,由于这些任务是属于同一个程序,通常没有必要利用进程所具有的严格的资源管理方式为每个任务分配独立的资源。由于进程之间的完全隔离性,在多任务进行切换时,进程的开销也较大。而线程共享进程中的资源,仅仅有少量的数据需要在线程之间进行隔离。创建一个线所需要的资源要远远小于创建进程。显然,线程之间通信的效率要高于进程之间的效率。

        说了那么多,现在该是使用线程的时候了。首先先让我们通过几个小程序来热热身。


1:

Thread myThread = new Thread( new ThreadStart(myFunc) );

        要运行线程我们首先我们要写

Thread t1 = new Thread( new ThreadStart(Incrementer) );

t1.Start()

        详细的代码如下

 

namespace Programming_CSharp
{
using System;
using System.Threading;
class Test
{
static void Main( )
{
// 生成一个本类的实例
Tester t = new Tester( );
t.DoTest( );
}

public void DoTest( )
{
//给Incrementer开一个线程并传入ThreadStart代理
Thread t1 =new Thread(new ThreadStart(Incrementer) );
//给Decrementer开一个线程并传入ThreadStart代理
Thread t2 =new Thread(new ThreadStart(Decrementer) );
// 线程开始
t1.Start( );
t2.Start( );
}

public void Incrementer( )
{
for (int i =0;i<1000;i++)
{
Console.WriteLine(
"增加: {0}", i);
}

}

public void Decrementer( )
{
for (int i = 1000;i>=0;i--)
{
Console.WriteLine(
"减少: {0}", i);
}

}

}

}


        输出:

增加: 102
增加: 
103
增加: 
104
增加: 
105
增加: 
106
减少: 
1000
减少: 
999
减少: 
998
减少: 
997


        阻塞线程

        阻塞调用线程,直到某个线程终止时为止

:

t2.Join( )


        线程挂起

        在某些情况下我们需要将某些正在运行中的程序挂起.

t2.Sleep(毫秒数)


 
        线程的高级使用
        异步调用
2

 

namespace Programming_CSharp
{
using System;
using System.Threading;
class Test
{
private int counter = 0;
static void Main( )
{
//生成一个本类的实例
Tester t = new Tester( );
t.DoTest( );
}

public void DoTest( )
{
Thread t1 
= new Thread( new ThreadStart(Incrementer) );
t1.IsBackground
=true;
t1.Name 
= "线程1";
t1.Start( );
Console.WriteLine(
"开始线程 {0}",
t1.Name);
Thread t2 
= new Thread( new ThreadStart(Incrementer) );
t2.IsBackground
=true;
t2.Name 
= "ThreadTwo";
t2.Start( );
Console.WriteLine(
"开始线程 {0}",
t2.Name);
t1.Join( );
t2.Join( );

Console.WriteLine(
"所有线程完成.");
}




public void Incrementer( )
{
try
{
while (counter < 1000)
{
int temp = counter;
temp
++// 增加
Thread.Sleep(1);
counter 
= temp;
Console.WriteLine(
"线程 {0}. 增加: {1}",Thread.CurrentThread.Name,counter);
}

}

catch (ThreadInterruptedException)
{
Console.WriteLine(
"线程 {0} 中断! 清空中…",Thread.CurrentThread.Name);
}

finally
{
Console.WriteLine(
"线程 {0} 退出. ",Thread.CurrentThread.Name);
}

}

}

}



输出:

 

线程开始 线程1
线程开始 线程2
线程 线程1. 增加: 
1
线程 线程2. 增加: 
2
线程 线程1. 增加: 
3
线程 线程2. 增加: 
4
线程 线程1. 增加: 
5
线程 线程2. 增加: 
6
线程 线程1. 增加: 
7
线程 线程2. 增加: 
8
线程 线程1. 增加: 
9
线程 线程2. 增加: 
10
线程 线程1 增加: 
11
线程 线程2. 增加: 
12
线程 线程1. 增加: 
13
线程 线程2. 增加: 
14
线程 线程1. 增加: 
15
线程 线程2. 增加: 
16
线程 线程1. 增加: 
17
线程 线程2. 增加: 
18
线程 线程2. 增加: 
20

        前面写的这些比较基础,主要是为了明确一些概念,熟悉常用的方法,方便从相关的源代码进行进一步学习,之后还会发一些线程高级应用的文章和一些例程,如果有问题请给我留言,我会尽量解答的。

posted @ 2006-07-03 01:34 ColinYang 阅读(2327) 评论(4) 编辑

2006年6月29日 #

一个我认为还不错的自动关机程序

摘要: 可以实现自动关机,我认为还是不错的.usingSystem;usingSystem.Drawing;usingSystem.Collections;usingSystem.ComponentModel;usingSystem.Windows.Forms;usingSystem.Data;usingSystem.Runtime.InteropServices;namespaceShutDownCom...阅读全文

posted @ 2006-06-29 02:47 ColinYang 阅读(1923) 评论(1) 编辑

用SHA1或MD5 算法加密数据(示例:对用户身份验证的简单实现)

摘要: (一).功能 用哈希算法: SHA1或MD5 实现用户账号和密码验证. 数据库存储实现原理是: 用户账号直接存储在数据库中,密码经过加密后再存储到数据库中. 当用户登录时,密码要经过加密后再与数据库中的实际存储密码比较,确定是否合法用户.(二).代码及实现 1.打开命名空间: usingSystem.Web.Security; 2.在用户注册界面,简要代码: Regist(UserID.Tex...阅读全文

posted @ 2006-06-29 02:14 ColinYang 阅读(1191) 评论(4) 编辑

2006年6月27日 #

转自别人的一个很有用的数据库连接类

摘要: usingSystem;usingSystem.Data;usingSystem.Data.SqlClient;usingSystem.Configuration;usingSystem.ComponentModel;namespaceSQLHelper{/**////<summary>///Class1的摘要说明。///</summary>publicclassSQLHe...阅读全文

posted @ 2006-06-27 22:16 ColinYang 阅读(527) 评论(3) 编辑

2006年6月26日 #

水晶按钮的制作

摘要: 现在我们可以把一个控件做的像水晶,是不是很Cool啊,来看看吧.usingSystem;usingSystem.Collections;usingSystem.ComponentModel;usingSystem.Drawing;usingSystem.Data;usingSystem.Windows.Forms;usingSystem.Drawing.Drawing2D;usingSystem....阅读全文

posted @ 2006-06-26 20:41 ColinYang 阅读(628) 评论(0) 编辑

将数据存入XML文件后帮入控件(Saving Data into Xml Files and Retriving into Winform controls)

摘要: Something maybe useful here.Let's go.A DataSet represents storage of data for efficient manipulation of data for an application. A dataset can contain multiple tables of results. The tables in a datas...阅读全文

posted @ 2006-06-26 20:27 ColinYang 阅读(226) 评论(0) 编辑

仅列出标题  下一页

导航

统计信息

News