Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
C#×ۺϽÒÃØ¡ª¡ªÏ¸Ëµ¶àỊ̈߳¨Ï£©
 
×÷Õß ·ç³¾ÀË×ӵIJ©¿Í£¬»ðÁú¹ûÈí¼þ    ·¢²¼ÓÚ 2014-08-04
  2935  次浏览      27
 

Æß¡¢²¢Ðбà³ÌÓëPLINQ

ҪʹÓöàÏ߳̿ª·¢£¬±ØÐë·Ç³£ÊìϤThreadµÄʹÓ㬶øÇÒÔÚ¿ª·¢¹ý³ÌÖпÉÄÜ»áÃæ¶ÔºÜ¶àδ֪µÄÎÊÌ⡣ΪÁ˼ò»¯¿ª·¢£¬.NET 4.0 ÌØ±ðÌṩһ¸ö²¢Ðбà³Ì¿âSystem.Threading.Tasks£¬Ëü¿ÉÒÔ¼ò»¯²¢Ðпª·¢£¬ÄãÎÞÐèÖ±½Ó¸úÏ̻߳òÏ̳߳شò½»µÀ£¬¾Í¿ÉÒÔ¼òµ¥½¨Á¢¶àÏß³ÌÓ¦ÓóÌÐò¡£´ËÍ⣬.NET»¹ÌṩÁËеÄÒ»×éÀ©Õ¹·½·¨PLINQ£¬Ëü¾ßÓÐ×Ô¶¯·ÖÎö²éѯ¹¦ÄÜ£¬Èç¹û²¢ÐвéѯÄÜÌá¸ßϵͳЧÂÊ£¬ÔòͬʱÔËÐУ¬Èç¹û²éѯδÄÜ´Ó²¢ÐвéѯÖÐÊÜÒæ£¬Ôò°´Ô­Ë³Ðò²éѯ¡£ÏÂÃæ½«Ïêϸ½éÉܲ¢ÐвÙ×÷µÄ·½Ê½¡£

7.1 ·ºÐÍίÍÐ

ʹÓò¢Ðбà³Ì¿ÉÒÔͬʱ²Ù×÷¶à¸öίÍÐ,ÔÚ½éÉܲ¢Ðбà³ÌǰÏȼòµ¥½éÉÜÒ»ÏÂÁ½¸ö·ºÐÍίÍÐSystem.Func<>ÓëSystem.Action<>¡£

Func<>ÊÇÒ»¸öÄܽÓÊܶà¸ö²ÎÊýºÍÒ»¸ö·µ»ØÖµµÄ·ºÐÍίÍУ¬ËüÄܽÓÊÜ0¸öµ½16¸öÊäÈë²ÎÊý, ÆäÖÐ T1,T2,T3,T4......T16 ´ú±í×Ô¶¨µÄÊäÈëÀàÐÍ£¬TResultΪ×Ô¶¨ÒåµÄ·µ»ØÖµ¡£

public delegate TResult Func<TResult>£¨£©
public delegate TResult Func<T1£¬TResult>£¨T1 arg1£©
public delegate TResult Func<T1£¬T2, TResult>£¨T1 arg1,T2 arg2£©
public delegate TResult Func<T1£¬T2, T3, TResult>£¨T1 arg1,T2 arg2,T3 arg3£©
public delegate TResult Func<T1£¬T2, T3, ,T4, TResult>£¨T1 arg1,T2 arg2,T3 arg3,T4 arg4£©
..............
public delegate TResult Func<T1£¬T2, T3, ,T4, ...... ,T16,TResult>£¨T1 arg1,T2 arg2,T3 arg3,T4 arg4£¬...... ,T16 arg16£©

Action<>ÓëFunc<>Ê®·ÖÏàËÆ£¬²»Í¬ÔÚÓÚAction<>µÄ·µ»ØÖµÎªvoid£¬ActionÄܽÓÊÜ0~16¸ö²ÎÊý

public delegate void Action<T1>£¨£©
public delegate void Action<T1£¬T2>£¨T1 arg1,T2 arg2£©
public delegate void Action<T1£¬T2, T3>£¨T1 arg1,T2 arg2, T3 arg3£©
.............
public delegate void Action<T1£¬T2, T3, ,T4, ...... ,T16>£¨T1 arg1,T2 arg2,T3 arg3,T4 arg4£¬...... ,T16 arg16£©

7.2 ÈÎÎñ²¢Ðп⣨TPL£©

System.Threading.TasksÖеÄÀ౻ͳ³ÆÎªÈÎÎñ²¢Ðп⣨Task Parallel Library£¬TPL£©£¬TPLʹÓÃCLRÏ̳߳ذѹ¤×÷·ÖÅäµ½CPU£¬²¢ÄÜ×Ô¶¯´¦Àí¹¤×÷·ÖÇø¡¢Ï̵߳÷¶È¡¢È¡ÏûÖ§³Ö¡¢×´Ì¬¹ÜÀíÒÔ¼°ÆäËûµÍ¼¶±ðµÄϸ½Ú²Ù×÷£¬¼«´óµØ¼ò»¯Á˶àÏ̵߳Ŀª·¢¡£

×¢Ò⣺TPL±ÈThread¸ü¾ßÖÇÄÜÐÔ£¬µ±ËüÅжÏÈÎÎñ¼¯²¢Ã»ÓдӲ¢ÐÐÔËÐÐÖÐÊÜÒæ£¬¾Í»áÑ¡Ôñ°´Ë³ÐòÔËÐС£µ«²¢·ÇËùÓеÄÏîÄ¿¶¼ÊʺÏʹÓò¢Ðпª·¢£¬´´½¨¹ý¶à²¢ÐÐÈÎÎñ¿ÉÄÜ»áË𺦳ÌÐòµÄÐÔÄÜ£¬½µµÍÔËÐÐЧÂÊ¡£

TPL°üÀ¨³£ÓõÄÊý¾Ý²¢ÐÐÓëÈÎÎñ²¢ÐÐÁ½ÖÖÖ´Ðз½Ê½£º

7.2.1 Êý¾Ý²¢ÐÐ

Êý¾Ý²¢ÐеĺËÐÄÀà¾ÍÊÇSystem.Threading.Tasks.Parallel£¬Ëü°üº¬Á½¸ö¾²Ì¬·½·¨ Parallel.For Óë Parallel.ForEach, ʹÓ÷½Ê½Óëfor¡¢foreachÏà·Â¡£Í¨¹ýÕâÁ½¸ö·½·¨¿ÉÒÔ²¢Ðд¦ÀíSystem.Func<>¡¢System.Action<>ίÍС£

ÒÔÏÂÒ»¸öÀý×Ó¾ÍÊÇÀûÓà public static ParallelLoopResult For( int from, int max, Action<int>) ·½·¨¶ÔList<Person>½øÐв¢Ðвéѯ¡£

¼ÙÉèʹÓõ¥Ï̷߳½Ê½²éѯ3¸öPerson¶ÔÏó£¬ÐèÒªÓÃʱ´óÔ¼6Ã룬ÔÚʹÓò¢Ðз½Ê½£¬Ö»ÐèʹÓÃ2Ãë¾ÍÄÜÍê³É²éѯ£¬¶øÇÒÄܹ»±Ü¿ªThreadµÄ·±Ëö´¦Àí¡£

class Program
{
static void Main(string[] args)
{
//ÉèÖÃ×î´óÏß³ÌÊý
ThreadPool.SetMaxThreads(1000, 1000);
//²¢Ðвéѯ
Parallel.For(0, 3,n =>
{
Thread.Sleep(2000); //Ä£Äâ²éѯ
ThreadPoolMessage(GetPersonList()[n]);
});
Console.ReadKey();
}

//Ä£ÄâÔ´Êý¾Ý
static IList<Person> GetPersonList()
{
var personList = new List<Person>();

var person1 = new Person();
person1.ID = 1;
person1.Name = "Leslie";
person1.Age = 30;
personList.Add(person1);
...........
return personList;
}

//ÏÔʾÏ̳߳ØÏÖ×´
static void ThreadPoolMessage(Person person)
{
int a, b;
ThreadPool.GetAvailableThreads(out a, out b);
string message = string.Format("Person ID:{0} Name:{1} Age:{2}\n" +
" CurrentThreadId is {3}\n WorkerThreads is:{4}" +
" CompletionPortThreads is :{5}\n",
person.ID, person.Name, person.Age,
Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());

Console.WriteLine(message);
}
}

¹Û²ìÔËÐнá¹û£¬¶ÔÏ󲢷ǰ´ÕÕÔ­ÅÅÁÐ˳Ðò½øÐвéѯ£¬¶øÊÇʹÓò¢Ðз½Ê½²éѯ¡£

ÈôÏëÍ£Ö¹²Ù×÷£¬¿ÉÒÔÀûÓÃParallelLoopState²ÎÊý£¬ÏÂÃæÒÔForEach×÷ΪÀý×Ó¡£

public static ParallelLoopResult ForEach<TSource>
( IEnumerable<TSource> source, Action<TSource,  ParallelLoopState> action)

ÆäÖÐsourceΪÊý¾Ý¼¯£¬ÔÚAction<TSource,ParallelLoopState>ίÍеÄParallelLoopState²ÎÊýµ±Öаüº¬ÓÐBreak£¨£©ºÍ Stop£¨£©Á½¸ö·½·¨¶¼¿ÉÒÔʹµü´úÍ£Ö¹¡£BreakµÄʹÓøú´«Í³forÀïÃæµÄʹÓ÷½Ê½ÏàËÆ£¬µ«ÒòΪ´¦ÓÚ²¢Ðд¦Àíµ±ÖУ¬Ê¹ÓÃBreak²¢²»Äܱ£Ö¤ËùÓÐÔËÐÐÄÜÁ¢¼´Í£Ö¹£¬ÔÚµ±Ç°µü´ú֮ǰµÄµü´ú»á¼ÌÐøÖ´ÐС£ÈôÏëÁ¢¼´Í£Ö¹²Ù×÷£¬¿ÉÒÔʹÓÃStop·½·¨£¬ËüÄܱ£Ö¤Á¢¼´ÖÕÖ¹ËùÓеIJÙ×÷£¬ÎÞÂÛËüÃÇÊÇ´¦ÓÚµ±Ç°µü´úµÄ֮ǰ»¹ÊÇÖ®ºó¡£

class Program
{
static void Main(string[] args)
{
//ÉèÖÃ×î´óÏß³ÌÊý
ThreadPool.SetMaxThreads(1000, 1000);

//²¢Ðвéѯ
Parallel.ForEach(GetPersonList(), (person, state) =>
{
if (person.ID == 2)
state.Stop();
ThreadPoolMessage(person);
});
Console.ReadKey();
}

//Ä£ÄâÔ´Êý¾Ý
static IList<Person> GetPersonList()
{
var personList = new List<Person>();

var person1 = new Person();
person1.ID = 1;
person1.Name = "Leslie";
person1.Age = 30;
personList.Add(person1);
..........
return personList;
}

//ÏÔʾÏ̳߳ØÏÖ×´
static void ThreadPoolMessage(Person person)
{
int a, b;
ThreadPool.GetAvailableThreads(out a, out b);
string message = string.Format("Person ID:{0} Name:{1} Age:{2}\n" +
" CurrentThreadId is {3}\n WorkerThreads is:{4}" +
" CompletionPortThreads is :{5}\n",
person.ID, person.Name, person.Age,
Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());

Console.WriteLine(message);
}
}

¹Û²ìÔËÐнá¹û£¬µ±PersonµÄIDµÈÓÚ2ʱ£¬ÔËÐн«»áÍ£Ö¹¡£

µ±ÒªÔÚ¶à¸öÏß³ÌÖе÷Óñ¾µØ±äÁ¿£¬¿ÉÒÔʹÓÃÒÔÏ·½·¨£º

public static ParallelLoopResult ForEach<TSource, 
                          TLocal>(IEnumerable<Of TSource>, Func<Of 
                          TLocal>, Func<Of TSource,ParallelLoopState,TLocal,TLocal>, 
                          Action<Of TLocal>)

ÆäÖеÚÒ»¸ö²ÎÊýΪÊý¾Ý¼¯;

µÚ¶þ¸ö²ÎÊýÊÇÒ»¸öFuncίÍУ¬ÓÃÓÚÔÚÿ¸öÏß³ÌÖ´ÐÐǰ½øÐгõʼ»¯;

µÚÈý¸ö²ÎÊýÊÇίÍÐFunc<Of T1,T2,T3,TResult>,ËüÄܶÔÊý¾Ý¼¯µÄÿ¸ö³ÉÔ±½øÐеü´ú£¬µ±ÖÐT1ÊÇÊý¾Ý¼¯µÄ³ÉÔ±£¬T2ÊÇÒ»¸öParallelLoopState¶Ô Ïó£¬Ëü¿ÉÒÔ¿ØÖƵü´úµÄ״̬£¬T3ÊÇÏß³ÌÖеı¾µØ±äÁ¿;

µÚËĸö²ÎÊýÊÇÒ»¸öActionίÍУ¬ÓÃÓÚ¶Ôÿ¸öÏ̵߳Ä×îÖÕ״̬½øÐÐ×îÖÕ²Ù×÷¡£

ÔÚÒÔÏÂÀý×ÓÖУ¬Ê¹ÓÃForEach¼ÆËã¶à¸öOrderµÄ×ÜÌå¼Û¸ñ¡£ÔÚForEach·½·¨ÖУ¬Ê×ÏȰѲÎÊý³õʼ»¯Îª0f£¬È»ºóÓðÑͬһ¸öOrderµÄ¶à¸öOrderItem¼Û¸ñ½øÐÐÀÛ¼Ó£¬¼ÆËã³öOrderµÄ¼Û¸ñ£¬×îºó°Ñ¶à¸öOrderµÄ¼Û¸ñ½øÐÐÀÛ¼Ó£¬¼ÆËã³ö¶à¸öOrderµÄ×ÜÌå¼Û¸ñ¡£

public class Order
{
public int ID;
public float Price;
}

public class OrderItem
{
public int ID;
public string Goods;
public int OrderID;
public float Price;
public int Count;
}

class Program
{
static void Main(string[] args)
{
//ÉèÖÃ×î´óÏß³ÌÊý
ThreadPool.SetMaxThreads(1000, 1000);
float totalPrice = 0f;
//²¢Ðвéѯ
var parallelResult = Parallel.ForEach(GetOrderList(),
() => 0f, //°Ñ²ÎÊý³õʼֵÉèΪ0
(order, state, orderPrice) =>
{
//¼ÆËãµ¥¸öOrderµÄ¼Û¸ñ
orderPrice = GetOrderItem().Where(item => item.OrderID == order.ID)
.Sum(item => item.Price * item.Count);
order.Price = orderPrice;
ThreadPoolMessage(order);

return orderPrice;
},
(finallyPrice) =>
{
totalPrice += finallyPrice;//¼ÆËã¶à¸öOrderµÄ×ÜÌå¼Û¸ñ
}
);

while (!parallelResult.IsCompleted)
Console.WriteLine("Doing Work!");

Console.WriteLine("Total Price is:" + totalPrice);
Console.ReadKey();
}
//ÐéÄâÊý¾Ý
static IList<Order> GetOrderList()
{
IList<Order> orderList = new List<Order>();
Order order1 = new Order();
order1.ID = 1;
orderList.Add(order1);
............
return orderList;
}
//ÐéÄâÊý¾Ý
static IList<OrderItem> GetOrderItem()
{
IList<OrderItem> itemList = new List<OrderItem>();

OrderItem orderItem1 = new OrderItem();
orderItem1.ID = 1;
orderItem1.Goods = "iPhone 4S";
orderItem1.Price = 6700;
orderItem1.Count = 2;
orderItem1.OrderID = 1;
itemList.Add(orderItem1);
...........
return itemList;
}

//ÏÔʾÏ̳߳ØÏÖ×´
static void ThreadPoolMessage(Order order)
{
int a, b;
ThreadPool.GetAvailableThreads(out a, out b);
string message = string.Format("OrderID:{0} OrderPrice:{1}\n" +
" CurrentThreadId is {2}\n WorkerThreads is:{3}" +
" CompletionPortThreads is:{4}\n",
order.ID, order.Price,
Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());

Console.WriteLine(message);
}
}

ÔËÐнá¹û

7.2.2 ÈÎÎñ²¢ÐÐ

ÔÚTPLµ±Öл¹¿ÉÒÔʹÓÃParallel.Invoke·½·¨´¥·¢¶à¸öÒì²½ÈÎÎñ,ÆäÖÐ actions ÖпÉÒÔ°üº¬¶à¸ö·½·¨»òÕßίÍУ¬parallelOptionsÓÃÓÚÅäÖÃParallelÀàµÄ²Ù×÷¡£

public static void Invoke(Action[] actions )
public static void Invoke(ParallelOptions parallelOptions, Action[] actions )

ÏÂÃæÀý×ÓÖÐÀûÓÃÁËParallet.Invoke²¢Ðвéѯ¶à¸öPerson£¬actionsµ±ÖпÉÒ԰󶨷½·¨¡¢lambda±í´ïʽ»òÕßίÍУ¬×¢Òâ°ó¶¨·½·¨Ê±±ØÐëÊÇ·µ»ØÖµÎªvoidµÄÎÞ²ÎÊý·½·¨¡£

class Program
{
static void Main(string[] args)
{
//ÉèÖÃ×î´óÏß³ÌÊý
ThreadPool.SetMaxThreads(1000, 1000);

//ÈÎÎñ²¢ÐÐ
Parallel.Invoke(option,
PersonMessage,
()=>ThreadPoolMessage(GetPersonList()[1]),
delegate(){
ThreadPoolMessage(GetPersonList()[2]);
});
Console.ReadKey();
}

static void PersonMessage()
{
ThreadPoolMessage(GetPersonList()[0]);
}

//ÏÔʾÏ̳߳ØÏÖ×´
static void ThreadPoolMessage(Person person)
{
int a, b;
ThreadPool.GetAvailableThreads(out a, out b);
string message = string.Format("Person ID:{0} Name:{1} Age:{2}\n" +
" CurrentThreadId is {3}\n WorkerThreads is:{4}" +
" CompletionPortThreads is :{5}\n",
person.ID, person.Name, person.Age,
Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());

Console.WriteLine(message);
}

//Ä£ÄâÔ´Êý¾Ý
static IList<Person> GetPersonList()
{
var personList = new List<Person>();

var person1 = new Person();
person1.ID = 1;
person1.Name = "Leslie";
person1.Age = 30;
personList.Add(person1);
..........
return personList;
}
}

ÔËÐнá¹û

7.3 Task¼ò½é

ÒÔThread´´½¨µÄÏ̱߳»Ä¬ÈÏΪǰ̨Ị̈߳¬µ±È»Äã¿ÉÒÔ°ÑÏß³ÌIsBackgroundÊôÐÔÉèÖÃΪtrue£¬µ«TPLΪ´ËÌṩÁËÒ»¸ö¸ü¼òµ¥µÄÀàTask¡£
Task´æÔÚÓÚSystem.Threading.TasksÃüÃû¿Õ¼äµ±ÖУ¬Ëü¿ÉÒÔ×÷ΪÒ첽ίÍеļòµ¥Ìæ´úÆ·¡£

ͨ¹ýTaskµÄFactoryÊôÐÔ½«·µ»ØTaskFactoryÀ࣬ÒÔTaskFactory.StartNew£¨Action£©·½·¨¿ÉÒÔ´´½¨Ò»¸öÐÂỊ̈߳¬Ëù´´½¨µÄÏß³ÌĬÈÏΪºǫ́Ï̡߳£

class Program
{
static void Main(string[] args)
{
ThreadPool.SetMaxThreads(1000, 1000);
Task.Factory.StartNew(() => ThreadPoolMessage());
Console.ReadKey();
}

//ÏÔʾÏ̳߳ØÏÖ×´
static void ThreadPoolMessage()
{
int a, b;
ThreadPool.GetAvailableThreads(out a, out b);
string message = string.Format("CurrentThreadId is:{0}\n" +
"CurrentThread IsBackground:{1}\n" +
"WorkerThreads is:{2}\nCompletionPortThreads is:{3}\n",
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsBackground.ToString(),
a.ToString(), b.ToString());
Console.WriteLine(message);
}
}

ÔËÐнá¹û

ÈôҪȡÏû´¦Àí£¬¿ÉÒÔÀûÓÃCancellationTakenSource¶ÔÏó£¬ÔÚTaskFactoryÖаüº¬Óз½·¨

public Task StartNew( Action action, CancellationToken cancellationToken )

ÔÚ·½·¨ÖмÓÈëCancellationTakenSource¶ÔÏóµÄCancellationTokenÊôÐÔ£¬¿ÉÒÔ¿ØÖÆÈÎÎñµÄÔËÐУ¬µ÷ÓÃCancellationTakenSource.CancelʱÈÎÎñ¾Í»á×Ô¶¯Í£Ö¹¡£ÏÂÃæÒÔͼƬÏÂÔØÎªÀý×Ó½éÉÜÒ»ÏÂTaskFactoryµÄʹÓá£

·þÎñÆ÷¶ËÒ³Ãæ

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/C#" runat="server">
private static List<string> url=new List<string>();

protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
url.Clear();
Application["Url"] = null;
}
}

protected void CheckBox_CheckedChanged(object sender, EventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
if (checkBox.Checked)
url.Add(checkBox.Text);
else
url.Remove(checkBox.Text);
Application["Url"]= url;
}
</script>
</head>
<body>
<form id="form1" runat="server" >
<div align="left">
<div align="center" style="float: left;">
<asp:Image ID="Image1" runat="server" ImageUrl="~/Images/A.jpg" /><br />
<asp:CheckBox ID="CheckBox1" runat="server" AutoPostBack="True"
oncheckedchanged="CheckBox_CheckedChanged" Text="A.jpg" />
</div>
<div align="center" style="float: left">
<asp:Image ID="Image2" runat="server" ImageUrl="~/Images/B.jpg" /><br />
<asp:CheckBox ID="CheckBox2" runat="server" AutoPostBack="True"
oncheckedchanged="CheckBox_CheckedChanged" Text="B.jpg" />
</div>
<div align="center" style="float: left">
<asp:Image ID="Image3" runat="server" ImageUrl="~/Images/C.jpg" /><br />
<asp:CheckBox ID="CheckBox3" runat="server" AutoPostBack="True"
oncheckedchanged="CheckBox_CheckedChanged" Text="C.jpg" />
</div>
<div align="center" style="float: left">
<asp:Image ID="Image4" runat="server" ImageUrl="~/Images/D.jpg" /><br />
<asp:CheckBox ID="CheckBox4" runat="server" AutoPostBack="True"
oncheckedchanged="CheckBox_CheckedChanged" Text="D.jpg" />
</div>
<div align="center" style="float: left">
<asp:Image ID="Image5" runat="server" ImageUrl="~/Images/E.jpg" /><br />
<asp:CheckBox ID="CheckBox5" runat="server" AutoPostBack="True"
oncheckedchanged="CheckBox_CheckedChanged" Text="E.jpg" />
</div>
</div>
</form>
</body>
</html>

Ê×ÏÈÔÚ·þÎñÆ÷Ò³ÃæÖÐÏÔʾ¶à¸ö*.jpgͼƬ£¬Ã¿¸öͼƬ¶¼ÓжÔÓ¦µÄCheckBox¼ì²âÆäÑ¡ÔñÇé¿ö¡£
ËùÑ¡ÔñͼƬµÄ·¾¶»á¼Ç¼ÔÚApplication["Url"]µ±Öд«µÝµ½Handler.ashxµ±ÖС£

×¢Ò⣺ApplicationÊÇÒ»¸öÈ«¾Ö±äÁ¿£¬´Ë´¦Ö»ÊÇΪÁËÏÔʾTaskµÄʹÓ÷½Ê½£¬ÔÚASP.NET¿ª·¢Ó¦¸ÃÉ÷ÓÃApplication¡£

Handler.ashx ´¦ÀíͼƬµÄÏÂÔØ£¬Ëü´Ó Application["Url"] µ±ÖлñÈ¡ËùÑ¡ÔñͼƬµÄ·¾¶£¬²¢°ÑͼƬת»¯³Ébyte[]¶þ½øÖÆÊý¾Ý¡£

ÔÙ°ÑͼƬµÄÊýÁ¿£¬Ã¿¸±Í¼Æ¬µÄ¶þ½øÖÆÊý¾ÝµÄ³¤¶È¼Ç¼ÔÚOutputStreamµÄÍ·²¿¡£

×îºó°ÑͼƬµÄ¶þ½øÖÆÊý¾Ý¼ÇÈë OutputStream Ò»²¢Êä³ö¡£

public class Handler : IHttpHandler 
{
public void ProcessRequest(HttpContext context)
{
//»ñȡͼƬÃû£¬°ÑͼƬÊýÁ¿Ð´OutputStream
List<String> urlList = (List<string>)context.Application["Url"];
context.Response.OutputStream.Write(BitConverter.GetBytes(urlList.Count), 0, 4);

//°ÑͼƬת»»³É¶þ½øÖÆÊý¾Ý
List<string> imageList = GetImages(urlList);

//°Ñÿ¸±Í¼Æ¬³¤¶ÈдÈëOutputStream
foreach (string image in imageList)
{
byte[] imageByte=Convert.FromBase64String(image);
context.Response.OutputStream.Write(BitConverter.GetBytes(imageByte.Length),0,4);
}

//°ÑͼƬдÈëOutputStream
foreach (string image in imageList)
{
byte[] imageByte = Convert.FromBase64String(image);
context.Response.OutputStream.Write(imageByte,0,imageByte.Length);
}
}

//»ñÈ¡¶à¸öͼƬµÄ¶þ½øÖÆÊý¾Ý
private List<string> GetImages(List<string> urlList)
{
List<string> imageList = new List<string>();
foreach (string url in urlList)
imageList.Add(GetImage(url));
return imageList;
}

//»ñÈ¡µ¥¸±Í¼Æ¬µÄ¶þ½øÖÆÊý¾Ý
private string GetImage(string url)
{
string path = "E:/My Projects/Example/WebSite/Images/"+url;
FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
byte[] imgBytes = new byte[10240];
int imgLength = stream.Read(imgBytes, 0, 10240);
return Convert.ToBase64String(imgBytes,0,imgLength);
}

public bool IsReusable
{
get{ return false;}
}
}

¿Í»§¶Ë

½¨Á¢Ò»¸öWinForm´°¿Ú£¬ÀïÃæ¼ÓÈëÒ»¸öWebBrowserÁ¬½Óµ½·þÎñÆ÷¶ËµÄDefault.aspxÒ³Ãæ¡£

µ±°´ÏÂDownload°´¼üʱ£¬ÏµÍ³¾Í»áÀûÓÃTaskFactory.StartNewµÄ·½·¨½¨Á¢Òì²½Ị̈߳¬Ê¹ÓÃWebRequest·½·¨ÏòHandler.ashx·¢ËÍÇëÇó¡£

½ÓÊÕµ½»Ø´«Á÷ʱ£¬¾Í»á¸ù¾ÝÍ·ÎļþµÄÄÚÈÝÅжÏͼƬµÄÊýÁ¿Óëÿ¸±Í¼Æ¬µÄ³¤¶È£¬°Ñ¶þ½øÖÆÊý¾Ýת»¯Îª*.jpgÎļþ±£´æ¡£

ϵͳÀûÓÃTaskFactory.StartNew(action,cancellationToken) ·½Ê½Òì²½µ÷ÓÃGetImages·½·¨½øÐÐͼƬÏÂÔØ¡£

µ±Óû§°´ÏÂCancel°´Å¥Ê±£¬Òì²½ÈÎÎñ¾Í»áÍ£Ö¹¡£ÖµµÃ×¢ÒâµÄÊÇ£¬ÔÚͼƬÏÂÔØÊ±µ÷ÓÃÁËCancellationToken.ThrowIfCancellationRequested·½·¨£¬Ä¿µÄÔÚ¼ì²é²¢ÐÐÈÎÎñµÄÔËÐÐÇé¿ö£¬ÔÚ²¢ÐÐÈÎÎñ±»Í£Ö¹Ê±ÊͷųöOperationCanceledExceptionÒì³££¬È·±£Óû§°´ÏÂCancel°´Å¥Ê±£¬Í£Ö¹ËùÓв¢ÐÐÈÎÎñ¡£

public partial class Form1 : Form
{
private CancellationTokenSource tokenSource = new CancellationTokenSource();

public Form1()
{
InitializeComponent();
ThreadPool.SetMaxThreads(1000, 1000);
}

private void downloadToolStripMenuItem_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(GetImages,tokenSource.Token);
}

private void cancelToolStripMenuItem_Click(object sender, EventArgs e)
{
tokenSource.Cancel();
}

private void GetImages()
{
//·¢ËÍÇëÇ󣬻ñÈ¡Êä³öÁ÷
WebRequest webRequest = HttpWebRequest.Create("Http://localhost:5800/Handler.ashx");
Stream responseStream=webRequest.GetResponse().GetResponseStream();

byte[] responseByte = new byte[81960];
IAsyncResult result=responseStream.BeginRead(responseByte,0,81960,null,null);
int responseLength = responseStream.EndRead(result);

//»ñȡͼƬÊýÁ¿
int imageCount = BitConverter.ToInt32(responseByte, 0);

//»ñȡÿ¸±Í¼Æ¬µÄ³¤¶È
int[] lengths = new int[imageCount];
for (int n = 0; n < imageCount; n++)
{
int length = BitConverter.ToInt32(responseByte, (n + 1) * 4);
lengths[n] = length;
}
try
{
//±£´æÍ¼Æ¬
for (int n = 0; n < imageCount; n++)
{
string path = string.Format("E:/My Projects/Example/Test/Images/pic{0}.jpg", n);
FileStream file = new FileStream(path, FileMode.Create, FileAccess.ReadWrite);

//¼ÆËã×Ö½ÚÆ«ÒÆÁ¿
int offset = (imageCount + 1) * 4;
for (int a = 0; a < n; a++)
offset += lengths[a];

file.Write(responseByte, offset, lengths[n]);
file.Flush();

//Ä£Äâ²Ù×÷
Thread.Sleep(1000);

//¼ì²âCancellationToken±ä»¯
tokenSource.Token.ThrowIfCancellationRequested();
}
}
catch (OperationCanceledException ex)
{
MessageBox.Show("Download cancel!");
}
}
}

7.4 ²¢Ðвéѯ£¨PLINQ£©

²¢ÐÐ LINQ (PLINQ) ÊÇ LINQ ģʽµÄ²¢ÐÐʵÏÖ£¬Ö÷񻂿±ðÔÚÓÚ PLINQ ³¢ÊÔ³ä·ÖÀûÓÃϵͳÖеÄËùÓд¦ÀíÆ÷¡£ ËüÀûÓÃËùÓд¦ÀíÆ÷µÄ·½·¨£¬°ÑÊý¾ÝÔ´·Ö³ÉƬ¶Î£¬È»ºóÔÚ¶à¸ö´¦ÀíÆ÷É϶Ե¥¶À¹¤×÷Ïß³ÌÉϵÄÿ¸öƬ¶Î²¢ÐÐÖ´Ðвéѯ£¬ ÔÚÐí¶àÇé¿öÏ£¬²¢ÐÐÖ´ÐÐÒâζ×ŲéѯÔËÐÐËÙ¶ÈÏÔÖøÌá¸ß¡£µ«Õâ²¢²»ËµÃ÷ËùÓÐPLINQ¶¼»áʹÓò¢Ðз½Ê½£¬µ±ÏµÍ³²âÊÔÒª²¢Ðвéѯ»á¶ÔϵͳÐÔÄÜÔì³ÉËðº¦Ê±£¬Äǽ«×Ô¶¯»¯µØÊ¹ÓÃͬ²½Ö´ÐС£

ÔÚSystem.Linq.ParallelEnumerableÀàÖУ¬°üº¬Á˲¢ÐвéѯµÄ´ó²¿·Ö·½·¨¡£

 

7.4.1 AsParallel

ͨ³£ÏëҪʵÏÖ²¢Ðвéѯ£¬Ö»ÐèÏòÊý¾ÝÔ´Ìí¼Ó AsParallel ²éѯ²Ù×÷¼´¿É¡£

class Program
{
static void Main(string[] args)
{
var personList=GetPersonList().AsParallel()
.Where(x=>x.Age>30);
Console.ReadKey();
}

//Ä£ÄâÔ´Êý¾Ý
static IList<Person> GetPersonList()
{
var personList = new List<Person>();

var person1 = new Person();
person1.ID = 1;
person1.Name = "Leslie";
person1.Age = 30;
personList.Add(person1);
...........
return personList;
}
}

7.4.2 AsOrdered

ÈôҪʹ²éѯ½á¹û±ØÐë±£ÁôÔ´ÐòÁÐÅÅÐò·½Ê½£¬¿ÉÒÔʹÓÃAsOrdered·½·¨¡£

AsOrderedÒÀȻʹÓò¢Ðз½Ê½£¬Ö»ÊÇÔÚ²éѯ¹ý³Ì¼ÓÈë¶îÍâÐÅÏ¢£¬ÔÚ²¢ÐнáÊøºó°Ñ²éѯ½á¹ûÔٴνøÐÐÅÅÁС£

class Program
{
static void Main(string[] args)
{
var personList=GetPersonList().AsParallel().AsOrdered()
.Where(x=>x.Age<30);
Console.ReadKey();
}

static IList<Person> GetPersonList()
{......}
}

7.4.3 WithDegreeOfParallelism

ĬÈÏÇé¿öÏ£¬PLINQ ʹÓÃÖ÷»úÉϵÄËùÓд¦ÀíÆ÷£¬ÕâЩ´¦ÀíÆ÷µÄÊýÁ¿×î¶à¿É´ï 64 ¸ö¡£

ͨ¹ýʹÓà WithDegreeOfParallelism(Of TSource) ·½·¨£¬¿ÉÒÔָʾ PLINQ ʹÓò»¶àÓÚÖ¸¶¨ÊýÁ¿µÄ´¦ÀíÆ÷¡£

class Program
{
static void Main(string[] args)
{
var personList=GetPersonList().AsParallel().WithDegreeOfParallelism(2)
.Where(x=>x.Age<30);
Console.ReadKey();
}

static IList<Person> GetPersonList()
{.........}
}

7.4.4 ForAll

Èç¹ûÒª¶Ô²¢Ðвéѯ½á¹û½øÐвÙ×÷£¬Ò»°ã»áÔÚfor»òforeachÖÐÖ´ÐУ¬Ö´ÐÐö¾Ù²Ù×÷ʱ»áʹÓÃͬ²½·½Ê½¡£

Óмû¼°´Ë£¬PLINQÖаüº¬ÁËForAll·½·¨£¬Ëü¿ÉÒÔʹÓò¢Ðз½Ê½¶ÔÊý¾Ý¼¯½øÐвÙ×÷¡£

class Program
{
static void Main(string[] args)
{
ThreadPool.SetMaxThreads(1000, 1000);
GetPersonList().AsParallel().ForAll(person =>{
ThreadPoolMessage(person);
});
Console.ReadKey();
}

static IList<Person> GetPersonList()
{.......}

//ÏÔʾÏ̳߳ØÏÖ×´
static void ThreadPoolMessage(Person person)
{
int a, b;
ThreadPool.GetAvailableThreads(out a, out b);
string message = string.Format("Person ID:{0} Name:{1} Age:{2}\n" +
" CurrentThreadId is {3}\n WorkerThreads is:{4}" +
" CompletionPortThreads is :{5}\n",
person.ID, person.Name, person.Age,
Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());
Console.WriteLine(message);
}
}

ÔËÐнá¹û

7.4.5 WithCancellation

Èç¹ûÐèҪֹͣ²éѯ£¬¿ÉÒÔʹÓà WithCancellation(Of TSource) ÔËËã·û²¢Ìṩ CancellationToken ʵÀý×÷Ϊ²ÎÊý¡£

ÓëµÚÈý½ÚTaskµÄÀý×ÓÏàËÆ£¬Èç¹û±ê¼ÇÉ쵀 IsCancellationRequested ÊôÐÔÉèÖÃΪ true£¬Ôò PLINQ ½«»á×¢Òâµ½Ëü£¬²¢Í£Ö¹ËùÓÐÏß³ÌÉϵĴ¦Àí£¬È»ºóÒý·¢ OperationCanceledException¡£Õâ¿ÉÒÔ±£Ö¤²¢ÐвéѯÄܹ»Á¢¼´Í£Ö¹¡£

class Program
{
static CancellationTokenSource tokenSource = new CancellationTokenSource();

static void Main(string[] args)
{
Task.Factory.StartNew(Cancel);
try
{
GetPersonList().AsParallel().WithCancellation(tokenSource.Token)
.ForAll(person =>
{
ThreadPoolMessage(person);
});
}
catch (OperationCanceledException ex)
{ }
Console.ReadKey();
}

//ÔÚ10~50ºÁÃëÄÚ·¢³öÍ£Ö¹ÐźÅ
static void Cancel()
{
Random random = new Random();
Thread.Sleep(random.Next(10,50));
tokenSource.Cancel();
}

static IList<Person> GetPersonList()
{......}

//ÏÔʾÏ̳߳ØÏÖ×´
static void ThreadPoolMessage(Person person)
{
int a, b;
ThreadPool.GetAvailableThreads(out a, out b);
string message = string.Format("Person ID:{0} Name:{1} Age:{2}\n" +
" CurrentThreadId is {3}\n WorkerThreads is:{4}" +
" CompletionPortThreads is :{5}\n",
person.ID, person.Name, person.Age,
Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());
Console.WriteLine(message);
}
}

 

°Ë¡¢¶¨Ê±Æ÷ÓëËø

8.1¶¨Ê±Æ÷

ÈôÒª³¤ÆÚ¶¨Ê±½øÐÐһЩ¹¤×÷£¬±ÈÈçÏñÓÊÏä¸üУ¬ÊµÊ±ÊÕÌýÐÅÏ¢µÈµÈ£¬¿ÉÒÔÀûÓö¨Ê±Æ÷Timer½øÐвÙ×÷¡£

ÔÚSystem.ThreadingÃüÃû¿Õ¼äÖдæÔÚTimerÀàÓë¶ÔÓ¦µÄTimerCallbackίÍУ¬Ëü¿ÉÒÔÔÚºǫ́Ïß³ÌÖÐÖ´ÐÐһЩ³¤ÆÚµÄ¶¨Ê±²Ù×÷£¬Ê¹Ö÷Ï̲߳»ÊܸÉÈÅ¡£

TimerÀàÖÐ×î³£ÓõĹ¹Ô캯ÊýΪ public Timer( timerCallback , object , int , int )

timerCallbackίÍпÉÒÔ°ó¶¨Ö´Ðз½·¨£¬Ö´Ðз½·¨±ØÐë·µ»Øvoid£¬Ëü¿ÉÒÔÊÇÎÞ²ÎÊý·½·¨£¬Ò²¿ÉÒÔ´øÒ»¸öobject²ÎÊýµÄ·½·¨¡£

µÚ¶þ¸ö²ÎÊýÊÇΪ timerCallback ίÍÐÊäÈëµÄ²ÎÊý¶ÔÏó¡£

µÚÈý¸ö²ÎÊýÊÇ¿ªÊ¼Ö´ÐÐǰµÈ´ýµÄʱ¼ä¡£

µÚËĸö²ÎÊýÊÇÿ´ÎÖ´ÐÐÖ®¼äµÄµÈ´ýʱ¼ä¡£

¿ª·¢ÊµÀý

class Program
{
static void Main(string[] args)
{
ThreadPool.SetMaxThreads(1000, 1000);

TimerCallback callback = new TimerCallback(ThreadPoolMessage);
Timer t = new Timer(callback,"Hello Jack! ", 0, 1000);
Console.ReadKey();
}

//ÏÔʾÏ̳߳ØÏÖ×´
static void ThreadPoolMessage(object data)
{
int a, b;
ThreadPool.GetAvailableThreads(out a, out b);
string message = string.Format("{0}\n CurrentThreadId is:{1}\n" +
" CurrentThread IsBackground:{2}\n" +
" WorkerThreads is:{3}\n CompletionPortThreads is:{4}\n",
data + "Time now is " + DateTime.Now.ToLongTimeString(),
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsBackground.ToString(),
a.ToString(), b.ToString());
Console.WriteLine(message);
}
}

×¢Òâ¹Û²ìÔËÐнá¹û£¬Ã¿´Îµ÷ÓÃTimer°ó¶¨µÄ·½·¨Ê±²»Ò»¶¨ÊÇʹÓÃͬһỊ̈߳¬µ«Ï̶߳¼»áÊÇÀ´×Ô¹¤×÷ÕßÏ̵߳ĺǫ́Ï̡߳£

8.2 Ëø

ÔÚʹÓöàÏ߳̿ª·¢Ê±£¬´æÔÚÒ»¶¨µÄ¹²ÓÃÊý¾Ý£¬ÎªÁ˱ÜÃâ¶àÏß³Ìͬʱ²Ù×÷ͬһÊý¾Ý£¬.NETÌṩÁËlock¡¢Monitor¡¢InterlockedµÈ¶à¸öËø¶¨Êý¾ÝµÄ·½Ê½¡£

8.2.1 lock

lockµÄʹÓñȽϼòµ¥£¬Èç¹ûÐèÒªËø¶¨Ä³¸ö¶ÔÏóʱ£¬¿ÉÒÔÖ±½ÓʹÓÃlock(this)µÄ·½Ê½¡£

private void Method()
{
lock(this)
{
//Ôڴ˽øÐеIJÙ×÷Äܱ£Ö¤ÔÚͬһʱ¼äÄÚÖ»ÓÐÒ»¸öÏ̶߳Դ˶ÔÏó²Ù×÷
}
}

Èç¹û²Ù×÷Ö»Ëø¶¨Ä³¶Î´úÂ룬¿ÉÒÔÊÂÏȽ¨Á¢Ò»¸öobject¶ÔÏ󣬲¢¶Ô´Ë¶ÔÏó½øÐвÙ×÷Ëø¶¨£¬ÕâÒ²ÊÇ.netÌᳫµÄËø¶¨Ó÷¨¡£

class Control
{
private object obj=new object();

public void Method()
{
lock(obj)
{.......}
}
}

8.2.2 Montior

Montior´æÔÚÓÚSystem.ThreadÃüÃû¿Õ¼äÄÚ£¬Ïà±Èlock£¬MontiorʹÓøüÁé»î¡£

Ëü´æÔÚ Enter, Exit Á½¸ö·½·¨£¬Ëü¿ÉÒÔ¶Ô¶ÔÏó½øÐÐËø¶¨Óë½âËø£¬±ÈlockʹÓøüÁé»î¡£

class Control
{
private object obj=new object();

public void Method()
{
Monitor.Enter(obj);
try
{......}
catch(Excetion ex)
{......}
finally
{
Monitor.Exit(obj);
}
}
}

ʹÓÃtryµÄ·½Ê½£¬ÄÜÈ·±£³ÌÐò²»»áÒòËÀËø¶øÊͷųöÒì³££¡

¶øÇÒÔÚfinallyÖÐÊÍ·Åobj¶ÔÏóÄܹ»È·±£ÎÞÂÛÊÇ·ñ³öÏÖËÀËø×´Ì¬£¬ÏµÍ³¶¼»áÊÍ·Åobj¶ÔÏó¡£

¶øÇÒMonitorÖл¹´æÔÚWait·½·¨¿ÉÒÔÈÃÏ̵߳ȴýÒ»¶Îʱ¼ä£¬È»ºóÔÚÍê³ÉʱʹÓÃPulse¡¢PulseAllµÈ·½·¨Í¨ÖªµÈ´ýÏ̡߳£

8.2.3 Interlocked

Interlocked´æÔÚÓÚSystem.ThreadÃüÃû¿Õ¼äÄÚ£¬ËüµÄ²Ù×÷±ÈMonitorʹÓøü¼òµ¥¡£

Ëü´æÔÚCompareExchange¡¢Decrement¡¢Exchange¡¢IncrementµÈ³£Ó÷½·¨ÈòÎÊýÔÚ°²È«µÄÇé¿ö½øÐÐÊý¾Ý½»»»¡£

Increment¡¢Decrement ¿ÉÒÔʹ²ÎÊý°²È«µØ¼Ó1»ò¼õ1²¢·µ»ØµÝÔöºóµÄÐÂÖµ¡£

class Example
{
private int a=1;

public void AddOne()
{
int newA=Interlocked.Increment(ref a);
}
}

Exchange¿ÉÒÔ°²È«µØ±äÁ¿¸³Öµ¡£

public void SetData()
2 {
3 Interlocked.Exchange(ref a,100);
4 }

CompareExchangeʹÓÃÌØ±ð·½±ã£¬ËüÏ൱ÓÚifµÄÓ÷¨£¬µ±aµÈÓÚ1ʱ£¬Ôò°Ñ100¸³Öµ¸øa¡£

public void CompareAndExchange()
2 {
3 Interlocked.CompareExchange(ref a,100,1);
4 }

½áÊøÓï

ÊìÏ¤ÕÆÎÕ¶àÏ߳̿ª·¢£¬¶ÔÌá¸ßϵͳ¹¤×÷ЧÂʷdz£ÓаïÖú£¬ÓÈÆäÊǻص÷·½·¨Óë×î½ü»ðÈȵIJ¢Ðбà³Ì¸üÓ¦¸ÃÒýÆð¸÷λµÄÖØÊÓ¡£

ÔÚÏÂÓÃÁ˽ϳ¤µÄʱ¼ä×ܽáËùÓùýµÄ¶àÏ߳̿ª·¢·½Ê½£¬Ï£Íû±¾ÆªÎÄÕÂÄܶԸ÷λµÄѧϰÑо¿ÓÐËù°ïÖú£¬µ±ÖÐÓÐËù´í©µÄµØ·½¾´ÇëµãÆÀ¡£

   
2935 ´Îä¯ÀÀ       27
 
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
 
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
 
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì
×îл¼Æ»®
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢ 6-12[ÏÃÃÅ]
È˹¤ÖÇÄÜ.»úÆ÷ѧϰTensorFlow 6-22[Ö±²¥]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 6-30[±±¾©]
ǶÈëʽÈí¼þ¼Ü¹¹-¸ß¼¶Êµ¼ù 7-9[±±¾©]
Óû§ÌåÑé¡¢Ò×ÓÃÐÔ²âÊÔÓëÆÀ¹À 7-25[Î÷°²]
ͼÊý¾Ý¿âÓë֪ʶͼÆ× 8-23[±±¾©]

ʹÓÃdecj¼ò»¯Webǰ¶Ë¿ª·¢
Web¿ª·¢¿ò¼ÜÐγÉÖ®ÂÃ
¸üÓÐЧÂʵÄʹÓÃVisual Studio
MVP+WCF+Èý²ã½á¹¹´î½¨¿ò¼Ü
ASP.NETÔËÐлúÖÆÇ³Îö¡¾Í¼½â¡¿
±àд¸üºÃµÄC#´úÂë
10¸öVisual Studio¿ª·¢µ÷ÊÔ¼¼ÇÉ


.NET¿ò¼ÜÓë·Ö²¼Ê½Ó¦Óüܹ¹Éè¼Æ
.NET & WPF & WCFÓ¦Óÿª·¢
UML&.Net¼Ü¹¹Éè¼Æ
COM×é¼þ¿ª·¢
.NetÓ¦Óÿª·¢
InstallShield


ÈÕÕÕ¸Û .NET Framework & WCFÓ¦Óÿª·¢
Éñ»ªÐÅÏ¢ .NETµ¥Ôª²âÊÔ
±±¾© .NetÓ¦ÓÃÈí¼þϵͳ¼Ü¹¹
̨´ïµç×Ó .NET³ÌÐòÉè¼ÆÓ뿪·¢
ÈüÃÅÌú¿Ë C#Óë.NET¼Ü¹¹Éè¼Æ
¹ã¶«ºËµç .NetÓ¦ÓÃϵͳ¼Ü¹¹