.net4.0新特性之线程同步

有时候我们可能需要使用多线程来执行同一任务,这个任务可能包含多步,而每步之间可能并不相干,但是这个任务必须让所有步骤执行完成后才能够进入下一步。这就如同WF中的并行任务。在.net4.0之前我们可能需要几个类来做到同步。但是现在我们只需要1个类就OK。

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
Console.WriteLine( " 任务启动 " );
using (CountdownEvent cd = new CountdownEvent( 1 ))
{
for (var i = 0 ; i < 5 ; i ++ )
{
cd.AddCount();
System.Threading.ThreadPool.QueueUserWorkItem(
(o)
=>
{
// do something
Console.WriteLine( " 线程: " +
Thread.CurrentThread.ManagedThreadId
+ " ,工作启动 " );
Thread.Sleep(
5000 );
cd.Signal();
Console.WriteLine(
" 线程: " + Thread.CurrentThread.ManagedThreadId + " ,工作完毕 " );
});
}
cd.Signal();
cd.Wait();
}

通过以上代码,我们看到只需要使用CountdownEvent类的AddCount() 和 Signal()方法 就可能实现线程同步。

此外,还有一个类也能够实现线程同步:Barrier。然而这个类不是通过使用增加减少信号量来实现同步。在程序执行时我们可呢个为这个类定义需要接到几个信号后同步任务完成进入下一个任务。

Barrier _barrier = new Barrier(3);//接到3个任务后同步目标达成,进入下一个任务。

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
Barrier _bar = new Barrier( 3 );
ThreadPool.QueueUserWorkItem(
(o)
=>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
_bar.SignalAndWait();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId
+ " is complete " );
Thread.Sleep(
2000 );
});
ThreadPool.QueueUserWorkItem(
(o)
=>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
_bar.SignalAndWait();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId
+ " is complete " );
Thread.Sleep(
2000 );
});
ThreadPool.QueueUserWorkItem(
(o)
=>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
_bar.SignalAndWait();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId
+ " is complete " );
Thread.Sleep(
2000 );
});
// 以上3个任务完成以后,下一个任务才会执行
ThreadPool.QueueUserWorkItem(
(o)
=>
{
Thread.Sleep(
2000 );
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
_bar.SignalAndWait();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId
+ " is complete " );
});

使用Task类进行任务控制:

1, 连续任务:

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
Task < int > task1 = new Task < int > (() =>
{
Console.WriteLine(
" Task1 " );
return 1 ;
});

Task task2
= task1.ContinueWith(
(prev)
=>
{
int result = prev.Result;
Console.WriteLine(
" Task2, " + result);
});
// task1执行完以后执行这个任务
task1.Start();

 2, 任务等待:

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
Task t1 = Task.Factory.StartNew(() => { Console.WriteLine( " task1 " ); });

Task t2
= Task.Factory.StartNew(() => { Console.WriteLine( " task2 " ); });

Task t3
= Task.Factory.StartNew(() => { Console.WriteLine( " task3 " ); });


Task.WaitAll(t1, t2, t3);
Console.WriteLine(
" continue " );

 

3, 容器任务

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
Task container = new Task(() =>
{
Task.Factory.StartNew(()
=> { Console.WriteLine( " first " ); });
Task.Factory.StartNew(()
=> { Console.WriteLine( " second " ); });
Task.Factory.StartNew(()
=> { Console.WriteLine( " third " ); });
});
container.Start();
// 等待整个任务的完成
container.Wait();
Console.WriteLine(
" continue " );
Console.ReadKey();

 

4, 任务监视

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
Task task1 = new Task(
()
=>
{
Console.WriteLine(
" task1 is start " );
int c = 0 ;
while (c < 10 )
{
Console.WriteLine(c);
Thread.Sleep(
1000 );
c
++ ;
}
});
task1.Start();
while ( ! task1.IsCompleted)
{
Console.WriteLine(
" task1 not complete,wait... " );
Thread.Sleep(
1000 );
}
Console.WriteLine(
" task1 is complete,continue! " );

 

转载于:https://www.cnblogs.com/GuoPeng/archive/2010/08/30/1812545.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值