WPF调用线程(三)线程池初步

论坛 期权论坛 脚本     
已经匿名di用户   2022-5-29 19:31   1170   0

当我们频繁的要调用线程来执行任务时,一个好的办法是采用线程池来对线程进行管理,
“线程池”是可以用来在后台执行多个任务的线程集合。 每个传入请求都将分配给线程池中的一个线程,因此可以异步处理请求,而不会占用主线程,也不会延迟后续请求的处理。一旦池中的某个线程完成任务,它将返回到等待线程队列中,等待被再次使用。 这使应用程序可以避免为每个任务创建新线程的开销。线程还是比较昂贵的。

(you must avoid using threads as much as possible because they consume a lot of memory and they require time to create, destroy,and manage . Time is also wasted when Windows context switches between threads and when garbage collections occur . However, this discussion should also help you realize that threads must be used sometimes because they allow Windows to be robust and responsive)摘自 CLR via C#


线程池通常具有最大线程数限制。 如果所有线程都繁忙,则额外的任务将放入队列中,直到有线程可用时才能够得到处理。

下面用WPF程序演示线程池基本的使用,运行效果如图:

XAML代码如下:

View Code

后台CS代码:

复制代码
  
1 namespace WpfThreadTest 2 { 3 /// <summary> 4 /// ThreadPoolDemo.xaml 的交互逻辑 5 /// </summary> 6 public partial class ThreadPoolDemo : Window 7 { 8 public ThreadPoolDemo() 9 { 10 InitializeComponent(); 11 /// 设置线程池的最大可用辅助线程数目,最大异步线程数目 12 ThreadPool.SetMaxThreads( 100 , 10 ); 13 14 } 15 16 private void button1_Click( object sender, RoutedEventArgs e) 17 { 18 // 调用线程去计算数字,仅供演示 19 ThreadPool.QueueUserWorkItem( new WaitCallback(CountNumber), 1 ); 20 } 21 private void CountNumber( object state) 22 { 23 int count = int .Parse(state.ToString()); 24 while ( true ) 25 { 26 count ++ ; 27 this .textBlock2.Dispatcher.Invoke( 28 DispatcherPriority.Normal, 29 new Action(() => 30 { 31 this .textBlock2.Text = count.ToString(); 32 })); 33 Thread.Sleep( 100 ); 34 } 35 } 36 /// <summary> 37 /// 测试线程中传递引用对象,以期望获得返回值 38 /// </summary> 39 /// <param name="state"></param> 40 private void ReturnValueMethod( object state) 41 { 42 MyParam myParam = state as MyParam; 43 myParam.MyInt = 100 ; 44 myParam.MyString = " updated string " ; 45 } 46 47 private void button2_Click( object sender, RoutedEventArgs e) 48 { 49 /// 将引用对象传递给线程 50 MyParam myParam = new MyParam() { MyInt = 12 , MyString = " test " }; 51 52 ThreadPool.QueueUserWorkItem( new WaitCallback(ReturnValueMethod), myParam); 53 54 /// 主线程睡眠5ms后,再去读取对象的值 55 /// 如果不睡眠,直接读取,可能读不到修改后的值,因为他们处于不同的线程当中 56 /// 当主线程去读取时,子线程尚未更改, 57 /// 即便如此,也会有读取不到的时候,故此种传值方式并不十分可取, 58 /// 具体线程返回值可以参考MSDN http://msdn.microsoft.com/zh-cn/library/wkays279.aspx 59 Thread.Sleep( 5 ); 60 this .textBlock1.Text = string .Format( " MyInt:{0},MyString:{1} " , myParam.MyInt, myParam.MyString); 61 } 62 63 private void button3_Click( object sender, RoutedEventArgs e) 64 { 65 ThreadPool.QueueUserWorkItem( new WaitCallback(GetThreadPoolInfo), null ); 66 } 67 private void GetThreadPoolInfo( object state) 68 { 69 while ( true ) 70 { 71 int workerThreads = 0 ; 72 int completionPortThreads = 0 ; 73 ThreadPool.GetAvailableThreads( out workerThreads, out completionPortThreads); 74 this .textBlock3.Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(() => 75 { 76 this .textBlock3.Text = 77 string .Format( " 池中可用辅助线程:{0},可用异步 I/O 线程:{1} " , 78 workerThreads, completionPortThreads); 79 })); 80 Thread.Sleep( 1000 ); 81 } 82 } 83 } 84 public class MyParam 85 { 86 public int MyInt { get ; set ; } 87 public string MyString { get ; set ; } 88 } 89 }
复制代码
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:81
帖子:4969
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP