2.0线程之Thread, Timer, BackgroundWorker, ThreadPool


介绍
Silverlight 2.0使用Thread, Timer, BackgroundWorker, ThreadPool来实现多线程开发
Thread - 用于线程的创建和控制的类
Timer - 用于以指定的时间间隔执行指定的方法的类
BackgroundWorker - 用于在单独的线程上运行操作
ThreadPool - 线程池的管理类


在线DEMO
http://www.cnblogs.com/webabcd/archive/2008/10/09/1307486.html


示例
1、Thread.xaml
<UserControlx:Class="Silverlight20.Thread.Thread"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanelHorizontalAlignment="Left"Margin="5">

<TextBlockx:Name="txtMsg"/>

</StackPanel>
</UserControl>

Thread.xaml.cs
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Net;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Documents;
usingSystem.Windows.Input;
usingSystem.Windows.Media;
usingSystem.Windows.Media.Animation;
usingSystem.Windows.Shapes;

namespaceSilverlight20.Thread
{
publicpartialclassThread:UserControl
{
stringresult="";

publicThread()
{
InitializeComponent();

Demo();
}


voidDemo()
{
/*
*Thread-用于线程的创建和控制的类
*Name-线程名称
*IsBackground-是否是后台线程(对于Silverlight来说,是否是后台线程没区别)
*Start(objectparameter)-启动后台线程
*objectparameter-为后台线程传递的参数
*IsAlive-线程是否在执行中
*ManagedThreadId-当前托管线程的唯一标识符
*ThreadState-指定线程的状态[System.Threading.ThreadState枚举]
*Abort()-终止线程
*/


//DoWork是后台线程所执行的方法(此处省略掉了委托类型)
//ThreadStart委托不可以带参数,ParameterizedThreadStart委托可以带参数
System.Threading.Threadthread=newSystem.Threading.Thread(DoWork);
thread.Name
="ThreadDemo";
thread.IsBackground
=true;
thread.Start(
1000);

result
+=thread.IsAlive+"\r\n";
result
+=thread.ManagedThreadId+"\r\n";
result
+=thread.Name+"\r\n";
result
+=thread.ThreadState+"\r\n";

//thread.Join();阻塞调用线程(本例为主线程),直到指定线程(本例为thread)执行完毕为止

//阻塞调用线程(本例为主线程)
//如果指定线程执行完毕则继续(本例为thread执行完毕则继续)
//如果指定线程运行的时间超过指定时间则继续(本例为thread执行时间如果超过5秒则继续)
//返回值为在指定时间内指定线程是否执行完毕(本例中thread的执行时间为1秒,所以会返回true)
if(thread.Join(5000))
{
result
+="指定线程在5秒内执行完毕\r\n";
}


txtMsg.Text
=result;
}


voidDoWork(objectsleepMillisecond)
{
System.Threading.Thread.Sleep((
int)sleepMillisecond);

result
+="新开线程执行完毕\r\n";
}

}

}



2、Timer.xaml
<UserControlx:Class="Silverlight20.Thread.Timer"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanelHorizontalAlignment="Left"Margin="5">

<TextBlockx:Name="txtMsg"/>

</StackPanel>
</UserControl>

Timer.xaml.cs
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Net;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Documents;
usingSystem.Windows.Input;
usingSystem.Windows.Media;
usingSystem.Windows.Media.Animation;
usingSystem.Windows.Shapes;

namespaceSilverlight20.Thread
{
publicpartialclassTimer:UserControl
{
System.Threading.SynchronizationContext_syncContext;
//Timer-用于以指定的时间间隔执行指定的方法的类
System.Threading.Timer_timer;
privateint_flag=0;

publicTimer()
{
InitializeComponent();

//UI线程
_syncContext=System.Threading.SynchronizationContext.Current;

Demo();
}


voidDemo()
{
//输出当前时间
txtMsg.Text=DateTime.Now.ToString()+"\r\n";

//第一个参数:定时器需要调用的方法
//第二个参数:传给需要调用的方法的参数
//第三个参数:此时间后启动定时器
//第四个参数:调用指定方法的间隔时间(System.Threading.Timeout.Infinite为无穷大)
_timer=newSystem.Threading.Timer(MyTimerCallback,"webabcd",3000,1000);
}


privatevoidMyTimerCallback(objectstate)
{
stringresult=string.Format("{0}-{1}\r\n",DateTime.Now.ToString(),(string)state);

//调用UI线程。不会做自动线程同步
_syncContext.Post(delegate{txtMsg.Text+=result;},null);

_flag
++;
if(_flag==5)
_timer.Change(
5000,500);//执行5次后,计时器重置为5秒后启动,每5毫秒的间隔时间执行一次指定的方法
elseif(_flag==10)
_timer.Dispose();
//执行10次后,释放计时器所使用的全部资源
}

}

}



3、BackgroundWorker.xaml
<UserControlx:Class="Silverlight20.Thread.BackgroundWorker"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanelHorizontalAlignment="Left"Margin="5">

<StackPanelOrientation="Horizontal"Margin="5">
<Buttonx:Name="btnStart"Content="开始"Margin="5"Click="btnStart_Click"/>
<Buttonx:Name="btnCancel"Content="取消"Margin="5"Click="btnCancel_Click"/>
</StackPanel>

<StackPanelMargin="5">
<TextBlockx:Name="txtProgress"Margin="5"/>
<TextBlockx:Name="txtMsg"Margin="5"/>
</StackPanel>

</StackPanel>
</UserControl>

BackgroundWorker.xaml.cs
/*
*演示用BackgroundWorker在后台线程上执行耗时的操作
*按“开始”键,开始在后台线程执行耗时操作,并向UI线程汇报执行进度
*按“取消”键,终止后台线程
*BackgroundWorker调用UI线程时会自动做线程同步
*/


usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Net;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Documents;
usingSystem.Windows.Input;
usingSystem.Windows.Media;
usingSystem.Windows.Media.Animation;
usingSystem.Windows.Shapes;

namespaceSilverlight20.Thread
{
publicpartialclassBackgroundWorker:UserControl
{
//BackgroundWorker-用于在单独的线程上运行操作。例如可以在非UI线程上运行耗时操作,以避免UI停止响应
System.ComponentModel.BackgroundWorker_backgroundWorker;

publicBackgroundWorker()
{
InitializeComponent();

BackgroundWorkerDemo();
}


voidBackgroundWorkerDemo()
{
/*
*WorkerSupportsCancellation-是否支持在其他线程中取消该线程的操作
*WorkerReportsProgress-是否可以报告操作进度
*ProgressChanged-报告操作进度时触发的事件
*DoWork-BackgroundWorker调用RunWorkerAsync()方法时触发的事件。在此执行具体操作
*RunWorkerCompleted-操作完成/取消/出错时触发的事件
*/


_backgroundWorker
=newSystem.ComponentModel.BackgroundWorker();

_backgroundWorker.WorkerSupportsCancellation
=true;
_backgroundWorker.WorkerReportsProgress
=true;

_backgroundWorker.ProgressChanged
+=newSystem.ComponentModel.ProgressChangedEventHandler(_backgroundWorker_ProgressChanged);
_backgroundWorker.DoWork
+=newSystem.ComponentModel.DoWorkEventHandler(_backgroundWorker_DoWork);
_backgroundWorker.RunWorkerCompleted
+=newSystem.ComponentModel.RunWorkerCompletedEventHandler(_backgroundWorker_RunWorkerCompleted);
}


privatevoidbtnStart_Click(objectsender,RoutedEventArgse)
{
//IsBusy-指定的BackgroundWorker是否正在后台操作
//RunWorkerAsync(objectargument)-开始在后台线程执行指定的操作
//objectargument-需要传递到DoWork的参数
if(!_backgroundWorker.IsBusy)
_backgroundWorker.RunWorkerAsync(
"需要传递的参数");
}


privatevoidbtnCancel_Click(objectsender,RoutedEventArgse)
{
//CancelAsync()-取消BackgroundWorker正在执行的后台操作
if(_backgroundWorker.WorkerSupportsCancellation)
_backgroundWorker.CancelAsync();
}


void_backgroundWorker_DoWork(objectsender,System.ComponentModel.DoWorkEventArgse)
{
/*
*DoWorkEventArgs.Argument-RunWorkerAsync(objectargument)传递过来的参数
*DoWorkEventArgs.Cancel-取消操作
*DoWorkEventArgs.Result-操作的结果。将传递到RunWorkerCompleted所指定的方法
*BackgroundWorker.ReportProgress(intpercentProgress,objectuserState)-向ProgressChanged汇报操作的完成进度
*intpercentProgress-操作完成的百分比1%-100%
*objectuserState-传递到ProgressChanged的参数
*/


for(inti=0;i<10;i++)
{
if((_backgroundWorker.CancellationPending==true))
{
e.Cancel
=true;
break;
}

else
{
System.Threading.Thread.Sleep(
1000);
_backgroundWorker.ReportProgress((i
+1)*10,i);
}

}


e.Result
="操作已完成";
}


void_backgroundWorker_ProgressChanged(objectsender,System.ComponentModel.ProgressChangedEventArgse)
{
//ProgressChangedEventArgs.ProgressPercentage-ReportProgress传递过来的操作完成的百分比
//ProgressChangedEventArgs.UserState-ReportProgress传递过来的参数
txtProgress.Text=string.Format("完成进度:{0}%;参数:{1}",
e.ProgressPercentage,
e.UserState);
}


void_backgroundWorker_RunWorkerCompleted(objectsender,System.ComponentModel.RunWorkerCompletedEventArgse)
{
/*
*RunWorkerCompletedEventArgs.Error-DoWork时产生的错误
*RunWorkerCompletedEventArgs.Cancelled-后台操作是否已被取消
*RunWorkerCompletedEventArgs.Result-DoWork的结果
*/


if(e.Error!=null)
{
txtMsg.Text
+=e.Error.ToString()+"\r\n";
}

elseif(e.Cancelled)
{
txtMsg.Text
+="操作被取消\r\n";
}

else
{
txtMsg.Text
+=e.Result.ToString()+"\r\n";
}

}

}

}



4、ThreadPool.xaml
<UserControlx:Class="Silverlight20.Thread.ThreadPool"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanelHorizontalAlignment="Left"Margin="5">

<TextBlockx:Name="txtMsgQueueUserWorkItem"Text="clickhere"MouseLeftButtonDown="txtMsgQueueUserWorkItem_MouseLeftButtonDown"Margin="30"/>

<TextBlockx:Name="txtRegisterWaitForSingleObject"Text="clickhere"MouseLeftButtonDown="txtRegisterWaitForSingleObject_MouseLeftButtonDown"Margin="30"/>

</StackPanel>
</UserControl>

ThreadPool.xaml.cs
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Net;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Documents;
usingSystem.Windows.Input;
usingSystem.Windows.Media;
usingSystem.Windows.Media.Animation;
usingSystem.Windows.Shapes;

namespaceSilverlight20.Thread
{
publicpartialclassThreadPool:UserControl
{
publicThreadPool()
{
InitializeComponent();
}


privatevoidtxtMsgQueueUserWorkItem_MouseLeftButtonDown(objectsender,MouseButtonEventArgse)
{
//ThreadPool-线程池的管理类

//QueueUserWorkItem(WaitCallbackcallBack,Objectstate)-将指定方法加入线程池队列
//WaitCallbackcallBack-需要在新开线程里执行的方法
//Objectstate-传递给指定方法的参数
System.Threading.ThreadPool.QueueUserWorkItem(DoWork,DateTime.Now);
}


privatevoidDoWork(objectstate)
{
//作为线程管理策略的一部分,线程池在创建线程前会有一定的延迟
//也就是说线程入队列的时间和线程启动的时间之间有一定的间隔

DateTimedtJoin
=(DateTime)state;
DateTimedtStart
=DateTime.Now;
System.Threading.Thread.Sleep(
3000);
DateTimedtEnd
=DateTime.Now;

//Dispatcher.BeginInvoke()-在与Dispatcher相关联的线程上执行指定的操作。自动线程同步
this.Dispatcher.BeginInvoke(()=>
{
txtMsgQueueUserWorkItem.Text
+=string.Format("\r\n入队列时间{0}启动时间{1}完成时间{2}",
dtJoin.ToString(),dtStart.ToString(),dtEnd.ToString());
}
);
}



privatevoidtxtRegisterWaitForSingleObject_MouseLeftButtonDown(objectsender,MouseButtonEventArgse)
{
System.Threading.AutoResetEventdone
=newSystem.Threading.AutoResetEvent(false);

//为了传递RegisteredWaitHandle对象,要将其做一个封装
RegisteredWaitHandlePacketpacket=newRegisteredWaitHandlePacket();

//RegisterWaitForSingleObject-注册一个WaitHandle。在超时或发信号的情况下对指定的回调方法做调用
//第一个参数:需要注册的WaitHandle
//第二个参数:需要回调的方法(此处省略掉了委托类型)
//第三个参数:传递给回调方法的参数
//第四个参数:超时时间(到超时时间则调用指定的方法)
//第五个参数:是否为一次调用(是到超时时间一次性调用指定的方法,还是每次超时时间后都调用指定的方法)
packet.Handle=System.Threading.ThreadPool.RegisterWaitForSingleObject
(
done,
WaitOrTimer,
packet,
100,
false
);

System.Threading.Thread.Sleep(
555);
done.Set();
//发出信号,调用RegisterWaitForSingleObject所指定的方法
}


publicvoidWaitOrTimer(objectstate,booltimedOut)
{
RegisteredWaitHandlePacketpacket
=stateasRegisteredWaitHandlePacket;

//booltimedOut-是否是因为超时而执行到这里
if(!timedOut)
{
//如果不是因为超时而执行到这里(即因为AutoResetEvent发出了信号而执行到这里),则注销指定的RegisteredWaitHandle
packet.Handle.Unregister(null);
}


this.Dispatcher.BeginInvoke(()=>
{
txtRegisterWaitForSingleObject.Text
+=
String.Format(
"\r\n是否收到信号:{0}",(!timedOut).ToString());
}
);
}

}


///<summary>
///封装了RegisteredWaitHandle的类
///</summary>

publicclassRegisteredWaitHandlePacket
{
publicSystem.Threading.RegisteredWaitHandleHandle{get;set;}
}

}


优质内容筛选与推荐>>
1、android异常总结三 :R文件丢失
2、什么是mvvm
3、win 2003 安装 vs2005 sp1 问题1718
4、 世界杯与国产开源(一)
5、C#中抽象类和接口的区别与使用


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn